Update Linux to v5.10.109
Sourced from [1]
[1] https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.109.tar.xz
Change-Id: I19bca9fc6762d4e63bcf3e4cba88bbe560d9c76c
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index c18dee6..2c0ee2e 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -530,6 +530,17 @@
To compile this driver as a module, choose M here: the
module will be called zx-irdec.
+config IR_TOY
+ tristate "Infrared Toy and IR Droid"
+ depends on RC_CORE
+ depends on USB_ARCH_HAS_HCD
+ help
+ Say Y here if you want to use the Infrared Toy or IR Droid, USB
+ versions.
+
+ To compile this driver as a module, choose M here: the module will be
+ called ir_toy.
+
endif #RC_DEVICES
endif #RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index caeb51d..ff6a8fc 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -51,3 +51,4 @@
obj-$(CONFIG_IR_ZX) += zx-irdec.o
obj-$(CONFIG_IR_TANGO) += tango-ir.o
obj-$(CONFIG_RC_XBOX_DVD) += xbox_remote.o
+obj-$(CONFIG_IR_TOY) += ir_toy.o
diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c
index d5f839f..afae0af 100644
--- a/drivers/media/rc/bpf-lirc.c
+++ b/drivers/media/rc/bpf-lirc.c
@@ -35,11 +35,6 @@
.arg1_type = ARG_PTR_TO_CTX,
};
-/*
- * Currently rc-core does not support 64-bit scancodes, but there are many
- * known protocols with more than 32 bits. So, define the interface as u64
- * as a future-proof.
- */
BPF_CALL_4(bpf_rc_keydown, u32*, sample, u32, protocol, u64, scancode,
u32, toggle)
{
@@ -108,14 +103,16 @@
return &bpf_map_peek_elem_proto;
case BPF_FUNC_ktime_get_ns:
return &bpf_ktime_get_ns_proto;
+ case BPF_FUNC_ktime_get_boot_ns:
+ return &bpf_ktime_get_boot_ns_proto;
case BPF_FUNC_tail_call:
return &bpf_tail_call_proto;
case BPF_FUNC_get_prandom_u32:
return &bpf_get_prandom_u32_proto;
case BPF_FUNC_trace_printk:
- if (capable(CAP_SYS_ADMIN))
+ if (perfmon_capable())
return bpf_get_trace_printk_proto();
- /* fall through */
+ fallthrough;
default:
return NULL;
}
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index 82867a2..6049e5c 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -432,27 +432,27 @@
select_timeout:
if (dev->rx_fan_input_inuse) {
- dev->rdev->rx_resolution = US_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
+ dev->rdev->rx_resolution = ENE_FW_SAMPLE_PERIOD_FAN;
/* Fan input doesn't support timeouts, it just ends the
input with a maximum sample */
dev->rdev->min_timeout = dev->rdev->max_timeout =
- US_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
- ENE_FW_SAMPLE_PERIOD_FAN);
+ ENE_FW_SMPL_BUF_FAN_MSK *
+ ENE_FW_SAMPLE_PERIOD_FAN;
} else {
- dev->rdev->rx_resolution = US_TO_NS(sample_period);
+ dev->rdev->rx_resolution = sample_period;
/* Theoreticly timeout is unlimited, but we cap it
* because it was seen that on one device, it
* would stop sending spaces after around 250 msec.
* Besides, this is close to 2^32 anyway and timeout is u32.
*/
- dev->rdev->min_timeout = US_TO_NS(127 * sample_period);
- dev->rdev->max_timeout = US_TO_NS(200000);
+ dev->rdev->min_timeout = 127 * sample_period;
+ dev->rdev->max_timeout = 200000;
}
if (dev->hw_learning_and_tx_capable)
- dev->rdev->tx_resolution = US_TO_NS(sample_period);
+ dev->rdev->tx_resolution = sample_period;
if (dev->rdev->timeout > dev->rdev->max_timeout)
dev->rdev->timeout = dev->rdev->max_timeout;
@@ -798,7 +798,7 @@
dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space");
- ev.duration = US_TO_NS(hw_sample);
+ ev.duration = hw_sample;
ev.pulse = pulse;
ir_raw_event_store_with_filter(dev->rdev, &ev);
}
@@ -818,7 +818,7 @@
dev->learning_mode_enabled = learning_mode_force;
/* Set reasonable default timeout */
- dev->rdev->timeout = US_TO_NS(150000);
+ dev->rdev->timeout = MS_TO_US(150);
}
/* Upload all hardware settings at once. Used at load and resume time */
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index b74bb13..b0d5805 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -51,13 +51,6 @@
fintek_cr_write(fintek, tmp, reg);
}
-/* clear config register bit without changing other bits */
-static inline void fintek_clear_reg_bit(struct fintek_dev *fintek, u8 val, u8 reg)
-{
- u8 tmp = fintek_cr_read(fintek, reg) & ~val;
- fintek_cr_write(fintek, tmp, reg);
-}
-
/* enter config mode */
static inline void fintek_config_mode_enable(struct fintek_dev *fintek)
{
@@ -306,8 +299,8 @@
case PARSE_IRDATA:
fintek->rem--;
rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
- rawir.duration = US_TO_NS((sample & BUF_SAMPLE_MASK)
- * CIR_SAMPLE_PERIOD);
+ rawir.duration = (sample & BUF_SAMPLE_MASK)
+ * CIR_SAMPLE_PERIOD;
fit_dbg("Storing %s with duration %d",
rawir.pulse ? "pulse" : "space",
@@ -531,9 +524,9 @@
rdev->dev.parent = &pdev->dev;
rdev->driver_name = FINTEK_DRIVER_NAME;
rdev->map_name = RC_MAP_RC6_MCE;
- rdev->timeout = US_TO_NS(1000);
+ rdev->timeout = 1000;
/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
- rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
+ rdev->rx_resolution = CIR_SAMPLE_PERIOD;
fintek->rdev = rdev;
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index a204130..22e524b 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -11,6 +11,8 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
#include <linux/irq.h>
#include <media/rc-core.h>
@@ -20,17 +22,38 @@
struct rc_dev *rcdev;
struct gpio_desc *gpiod;
int irq;
+ struct device *pmdev;
+ struct pm_qos_request qos;
};
static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id)
{
int val;
struct gpio_rc_dev *gpio_dev = dev_id;
+ struct device *pmdev = gpio_dev->pmdev;
+
+ /*
+ * For some cpuidle systems, not all:
+ * Respond to interrupt taking more latency when cpu in idle.
+ * Invoke asynchronous pm runtime get from interrupt context,
+ * this may introduce a millisecond delay to call resume callback,
+ * where to disable cpuilde.
+ *
+ * Two issues lead to fail to decode first frame, one is latency to
+ * respond to interrupt, another is delay introduced by async api.
+ */
+ if (pmdev)
+ pm_runtime_get(pmdev);
val = gpiod_get_value(gpio_dev->gpiod);
if (val >= 0)
ir_raw_event_store_edge(gpio_dev->rcdev, val == 1);
+ if (pmdev) {
+ pm_runtime_mark_last_busy(pmdev);
+ pm_runtime_put_autosuspend(pmdev);
+ }
+
return IRQ_HANDLED;
}
@@ -40,6 +63,7 @@
struct device_node *np = dev->of_node;
struct gpio_rc_dev *gpio_dev;
struct rc_dev *rcdev;
+ u32 period = 0;
int rc;
if (!np)
@@ -90,6 +114,15 @@
return rc;
}
+ of_property_read_u32(np, "linux,autosuspend-period", &period);
+ if (period) {
+ gpio_dev->pmdev = dev;
+ pm_runtime_set_autosuspend_delay(dev, period);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_enable(dev);
+ }
+
platform_set_drvdata(pdev, gpio_dev);
return devm_request_irq(dev, gpio_dev->irq, gpio_ir_recv_irq,
@@ -122,9 +155,29 @@
return 0;
}
+static int gpio_ir_recv_runtime_suspend(struct device *dev)
+{
+ struct gpio_rc_dev *gpio_dev = dev_get_drvdata(dev);
+
+ cpu_latency_qos_remove_request(&gpio_dev->qos);
+
+ return 0;
+}
+
+static int gpio_ir_recv_runtime_resume(struct device *dev)
+{
+ struct gpio_rc_dev *gpio_dev = dev_get_drvdata(dev);
+
+ cpu_latency_qos_add_request(&gpio_dev->qos, 0);
+
+ return 0;
+}
+
static const struct dev_pm_ops gpio_ir_recv_pm_ops = {
.suspend = gpio_ir_recv_suspend,
.resume = gpio_ir_recv_resume,
+ .runtime_suspend = gpio_ir_recv_runtime_suspend,
+ .runtime_resume = gpio_ir_recv_runtime_resume,
};
#endif
diff --git a/drivers/media/rc/gpio-ir-tx.c b/drivers/media/rc/gpio-ir-tx.c
index 6670398..c6cd2e6 100644
--- a/drivers/media/rc/gpio-ir-tx.c
+++ b/drivers/media/rc/gpio-ir-tx.c
@@ -19,8 +19,6 @@
struct gpio_desc *gpio;
unsigned int carrier;
unsigned int duty_cycle;
- /* we need a spinlock to hold the cpu while transmitting */
- spinlock_t lock;
};
static const struct of_device_id gpio_ir_tx_of_match[] = {
@@ -42,7 +40,7 @@
{
struct gpio_ir *gpio_ir = dev->priv;
- if (!carrier)
+ if (carrier > 500000)
return -EINVAL;
gpio_ir->carrier = carrier;
@@ -50,11 +48,32 @@
return 0;
}
-static int gpio_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
- unsigned int count)
+static void gpio_ir_tx_unmodulated(struct gpio_ir *gpio_ir, uint *txbuf,
+ uint count)
{
- struct gpio_ir *gpio_ir = dev->priv;
- unsigned long flags;
+ ktime_t edge;
+ s32 delta;
+ int i;
+
+ local_irq_disable();
+
+ edge = ktime_get();
+
+ for (i = 0; i < count; i++) {
+ gpiod_set_value(gpio_ir->gpio, !(i % 2));
+
+ edge = ktime_add_us(edge, txbuf[i]);
+ delta = ktime_us_delta(edge, ktime_get());
+ if (delta > 0)
+ udelay(delta);
+ }
+
+ gpiod_set_value(gpio_ir->gpio, 0);
+}
+
+static void gpio_ir_tx_modulated(struct gpio_ir *gpio_ir, uint *txbuf,
+ uint count)
+{
ktime_t edge;
/*
* delta should never exceed 0.5 seconds (IR_MAX_DURATION) and on
@@ -70,7 +89,7 @@
space = DIV_ROUND_CLOSEST((100 - gpio_ir->duty_cycle) *
(NSEC_PER_SEC / 100), gpio_ir->carrier);
- spin_lock_irqsave(&gpio_ir->lock, flags);
+ local_irq_disable();
edge = ktime_get();
@@ -103,8 +122,20 @@
edge = last;
}
}
+}
- spin_unlock_irqrestore(&gpio_ir->lock, flags);
+static int gpio_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
+ unsigned int count)
+{
+ struct gpio_ir *gpio_ir = dev->priv;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (gpio_ir->carrier)
+ gpio_ir_tx_modulated(gpio_ir, txbuf, count);
+ else
+ gpio_ir_tx_unmodulated(gpio_ir, txbuf, count);
+ local_irq_restore(flags);
return count;
}
@@ -140,7 +171,6 @@
gpio_ir->carrier = 38000;
gpio_ir->duty_cycle = 50;
- spin_lock_init(&gpio_ir->lock);
rc = devm_rc_register_device(&pdev->dev, rcdev);
if (rc < 0)
diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
index b981f72..3e9988e 100644
--- a/drivers/media/rc/igorplugusb.c
+++ b/drivers/media/rc/igorplugusb.c
@@ -64,12 +64,14 @@
if (start >= len) {
dev_err(ir->dev, "receive overflow invalid: %u", overflow);
} else {
- if (overflow > 0)
+ if (overflow > 0) {
dev_warn(ir->dev, "receive overflow, at least %u lost",
overflow);
+ ir_raw_event_reset(ir->rc);
+ }
do {
- rawir.duration = ir->buf_in[i] * 85333;
+ rawir.duration = ir->buf_in[i] * 85;
rawir.pulse = i & 1;
ir_raw_event_store_with_filter(ir->rc, &rawir);
@@ -202,8 +204,8 @@
rc->priv = ir;
rc->driver_name = DRIVER_NAME;
rc->map_name = RC_MAP_HAUPPAUGE;
- rc->timeout = MS_TO_NS(100);
- rc->rx_resolution = 85333;
+ rc->timeout = MS_TO_US(100);
+ rc->rx_resolution = 85;
ir->rc = rc;
ret = rc_register_device(rc);
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index a7deca1..84949ba 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -14,7 +14,6 @@
#include <linux/completion.h>
#include <media/rc-core.h>
-#define DRIVER_NAME "iguanair"
#define BUF_SIZE 152
struct iguanair {
@@ -27,8 +26,6 @@
uint8_t bufsize;
uint8_t cycle_overhead;
- struct mutex lock;
-
/* receiver support */
bool receiver_on;
dma_addr_t dma_in, dma_out;
@@ -62,7 +59,7 @@
#define MAX_IN_PACKET 8u
#define MAX_OUT_PACKET (sizeof(struct send_packet) + BUF_SIZE)
#define TIMEOUT 1000
-#define RX_RESOLUTION 21333
+#define RX_RESOLUTION 21
struct packet {
uint16_t start;
@@ -76,7 +73,7 @@
uint8_t channels;
uint8_t busy7;
uint8_t busy4;
- uint8_t payload[0];
+ uint8_t payload[];
};
static void process_ir_data(struct iguanair *ir, unsigned len)
@@ -104,7 +101,7 @@
break;
case CMD_TX_OVERFLOW:
ir->tx_overflow = true;
- /* fall through */
+ fallthrough;
case CMD_RECEIVER_OFF:
case CMD_RECEIVER_ON:
case CMD_SEND:
@@ -127,7 +124,7 @@
for (i = 0; i < 7; i++) {
if (ir->buf_in[i] == 0x80) {
rawir.pulse = false;
- rawir.duration = US_TO_NS(21845);
+ rawir.duration = 21845;
} else {
rawir.pulse = (ir->buf_in[i] & 0x80) == 0;
rawir.duration = ((ir->buf_in[i] & 0x7f) + 1) *
@@ -284,8 +281,6 @@
if (carrier < 25000 || carrier > 150000)
return -EINVAL;
- mutex_lock(&ir->lock);
-
if (carrier != ir->carrier) {
uint32_t cycles, fours, sevens;
@@ -314,8 +309,6 @@
ir->packet->busy4 = 110 - fours;
}
- mutex_unlock(&ir->lock);
-
return 0;
}
@@ -326,9 +319,7 @@
if (mask > 15)
return 4;
- mutex_lock(&ir->lock);
ir->packet->channels = mask << 4;
- mutex_unlock(&ir->lock);
return 0;
}
@@ -339,8 +330,6 @@
unsigned int i, size, p, periods;
int rc;
- mutex_lock(&ir->lock);
-
/* convert from us to carrier periods */
for (i = size = 0; i < count; i++) {
periods = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
@@ -368,8 +357,6 @@
rc = -EOVERFLOW;
out:
- mutex_unlock(&ir->lock);
-
return rc ? rc : count;
}
@@ -378,14 +365,10 @@
struct iguanair *ir = rdev->priv;
int rc;
- mutex_lock(&ir->lock);
-
rc = iguanair_receiver(ir, true);
if (rc == 0)
ir->receiver_on = true;
- mutex_unlock(&ir->lock);
-
return rc;
}
@@ -394,14 +377,10 @@
struct iguanair *ir = rdev->priv;
int rc;
- mutex_lock(&ir->lock);
-
rc = iguanair_receiver(ir, false);
ir->receiver_on = false;
if (rc && rc != -ENODEV)
dev_warn(ir->dev, "failed to disable receiver: %d\n", rc);
-
- mutex_unlock(&ir->lock);
}
static int iguanair_probe(struct usb_interface *intf,
@@ -441,7 +420,6 @@
ir->rc = rc;
ir->dev = &intf->dev;
ir->udev = udev;
- mutex_init(&ir->lock);
init_completion(&ir->completion);
pipeout = usb_sndintpipe(udev,
@@ -483,7 +461,7 @@
rc->s_tx_mask = iguanair_set_tx_mask;
rc->s_tx_carrier = iguanair_set_tx_carrier;
rc->tx_ir = iguanair_tx;
- rc->driver_name = DRIVER_NAME;
+ rc->driver_name = KBUILD_MODNAME;
rc->map_name = RC_MAP_RC6_MCE;
rc->min_timeout = 1;
rc->timeout = IR_DEFAULT_TIMEOUT;
@@ -538,8 +516,6 @@
struct iguanair *ir = usb_get_intfdata(intf);
int rc = 0;
- mutex_lock(&ir->lock);
-
if (ir->receiver_on) {
rc = iguanair_receiver(ir, false);
if (rc)
@@ -549,17 +525,13 @@
usb_kill_urb(ir->urb_in);
usb_kill_urb(ir->urb_out);
- mutex_unlock(&ir->lock);
-
return rc;
}
static int iguanair_resume(struct usb_interface *intf)
{
struct iguanair *ir = usb_get_intfdata(intf);
- int rc = 0;
-
- mutex_lock(&ir->lock);
+ int rc;
rc = usb_submit_urb(ir->urb_in, GFP_KERNEL);
if (rc)
@@ -571,8 +543,6 @@
dev_warn(ir->dev, "failed to enable receiver after resume\n");
}
- mutex_unlock(&ir->lock);
-
return rc;
}
@@ -582,7 +552,7 @@
};
static struct usb_driver iguanair_driver = {
- .name = DRIVER_NAME,
+ .name = KBUILD_MODNAME,
.probe = iguanair_probe,
.disconnect = iguanair_disconnect,
.suspend = iguanair_suspend,
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index c683a24..a7962ca 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -83,6 +83,7 @@
__u16 flags;
#define IMON_NO_FLAGS 0
#define IMON_NEED_20MS_PKT_DELAY 1
+#define IMON_SUPPRESS_REPEATED_KEYS 2
struct imon_panel_key_table key_table[];
};
@@ -149,8 +150,9 @@
struct timer_list ttimer; /* touch screen timer */
int touch_x; /* x coordinate on touchscreen */
int touch_y; /* y coordinate on touchscreen */
- struct imon_usb_dev_descr *dev_descr; /* device description with key
- table for front panels */
+ const struct imon_usb_dev_descr *dev_descr;
+ /* device description with key */
+ /* table for front panels */
};
#define TOUCH_TIMEOUT (HZ/30)
@@ -315,6 +317,32 @@
}
};
+/* imon ultrabay front panel key table */
+static const struct imon_usb_dev_descr ultrabay_table = {
+ .flags = IMON_SUPPRESS_REPEATED_KEYS,
+ .key_table = {
+ { 0x0000000f0000ffeell, KEY_MEDIA }, /* Go */
+ { 0x000000000100ffeell, KEY_UP },
+ { 0x000000000001ffeell, KEY_DOWN },
+ { 0x000000160000ffeell, KEY_ENTER },
+ { 0x0000001f0000ffeell, KEY_AUDIO }, /* Music */
+ { 0x000000200000ffeell, KEY_VIDEO }, /* Movie */
+ { 0x000000210000ffeell, KEY_CAMERA }, /* Photo */
+ { 0x000000270000ffeell, KEY_DVD }, /* DVD */
+ { 0x000000230000ffeell, KEY_TV }, /* TV */
+ { 0x000000050000ffeell, KEY_PREVIOUS }, /* Previous */
+ { 0x000000070000ffeell, KEY_REWIND },
+ { 0x000000040000ffeell, KEY_STOP },
+ { 0x000000020000ffeell, KEY_PLAYPAUSE },
+ { 0x000000080000ffeell, KEY_FASTFORWARD },
+ { 0x000000060000ffeell, KEY_NEXT }, /* Next */
+ { 0x000100000000ffeell, KEY_VOLUMEUP },
+ { 0x010000000000ffeell, KEY_VOLUMEDOWN },
+ { 0x000000010000ffeell, KEY_MUTE },
+ { 0, KEY_RESERVED },
+ }
+};
+
/*
* USB Device ID for iMON USB Control Boards
*
@@ -767,7 +795,7 @@
else
strscpy(buf, "closed\n", PAGE_SIZE);
- dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for instructions on how to associate your iMON 2.4G DT/LT remote\n");
+ dev_info(d, "Visit https://www.lirc.org/html/imon-24g.html for instructions on how to associate your iMON 2.4G DT/LT remote\n");
mutex_unlock(&ictx->lock);
return strlen(buf);
}
@@ -1264,9 +1292,11 @@
static u32 imon_panel_key_lookup(struct imon_context *ictx, u64 code)
{
- int i;
+ const struct imon_panel_key_table *key_table;
u32 keycode = KEY_RESERVED;
- struct imon_panel_key_table *key_table = ictx->dev_descr->key_table;
+ int i;
+
+ key_table = ictx->dev_descr->key_table;
for (i = 0; key_table[i].hw_code != 0; i++) {
if (key_table[i].hw_code == (code | 0xffee)) {
@@ -1550,7 +1580,6 @@
u32 kc;
u64 scancode;
int press_type = 0;
- long msec;
ktime_t t;
static ktime_t prev_time;
u8 ktype;
@@ -1652,14 +1681,16 @@
spin_lock_irqsave(&ictx->kc_lock, flags);
t = ktime_get();
- /* KEY_MUTE repeats from knob need to be suppressed */
- if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
- msec = ktime_ms_delta(t, prev_time);
- if (msec < ictx->idev->rep[REP_DELAY]) {
+ /* KEY repeats from knob and panel that need to be suppressed */
+ if (ictx->kc == KEY_MUTE ||
+ ictx->dev_descr->flags & IMON_SUPPRESS_REPEATED_KEYS) {
+ if (ictx->kc == ictx->last_keycode &&
+ ktime_ms_delta(t, prev_time) < ictx->idev->rep[REP_DELAY]) {
spin_unlock_irqrestore(&ictx->kc_lock, flags);
return;
}
}
+
prev_time = t;
kc = ictx->kc;
@@ -1847,6 +1878,14 @@
dev_info(ictx->dev, "0xffdc iMON Inside, iMON IR");
ictx->display_supported = false;
break;
+ /* Soundgraph iMON UltraBay */
+ case 0x98:
+ dev_info(ictx->dev, "0xffdc iMON UltraBay, LCD + IR");
+ detected_display_type = IMON_DISPLAY_TYPE_LCD;
+ allowed_protos = RC_PROTO_BIT_IMON | RC_PROTO_BIT_RC6_MCE;
+ ictx->dev_descr = &ultrabay_table;
+ break;
+
default:
dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR");
detected_display_type = IMON_DISPLAY_TYPE_VFD;
@@ -1978,10 +2017,12 @@
static struct input_dev *imon_init_idev(struct imon_context *ictx)
{
- struct imon_panel_key_table *key_table = ictx->dev_descr->key_table;
+ const struct imon_panel_key_table *key_table;
struct input_dev *idev;
int ret, i;
+ key_table = ictx->dev_descr->key_table;
+
idev = input_allocate_device();
if (!idev)
goto out;
diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c
index d4aedcf..d41580f 100644
--- a/drivers/media/rc/imon_raw.c
+++ b/drivers/media/rc/imon_raw.c
@@ -8,7 +8,7 @@
#include <media/rc-core.h>
/* Each bit is 250us */
-#define BIT_DURATION 250000
+#define BIT_DURATION 250
struct imon {
struct device *dev;
@@ -57,32 +57,18 @@
* fls will tell us the highest bit set plus 1 (or 0 if no
* bits are set).
*/
+ rawir.pulse = !rawir.pulse;
bit = fls64(data & (BIT_ULL(offset) - 1));
if (bit < offset) {
- dev_dbg(imon->dev, "pulse: %d bits", offset - bit);
- rawir.pulse = true;
+ dev_dbg(imon->dev, "%s: %d bits",
+ rawir.pulse ? "pulse" : "space", offset - bit);
rawir.duration = (offset - bit) * BIT_DURATION;
ir_raw_event_store_with_filter(imon->rcdev, &rawir);
- if (bit == 0)
- break;
-
offset = bit;
}
- /*
- * Find highest clear bit which is less than offset.
- *
- * Just invert the data and use same trick as above.
- */
- bit = fls64(~data & (BIT_ULL(offset) - 1));
- dev_dbg(imon->dev, "space: %d bits", offset - bit);
-
- rawir.pulse = false;
- rawir.duration = (offset - bit) * BIT_DURATION;
- ir_raw_event_store_with_filter(imon->rcdev, &rawir);
-
- offset = bit;
+ data = ~data;
} while (offset > 0);
if (packet_no == 0x0a && !imon->rcdev->idle) {
diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c
index 32ccefe..0ffc275 100644
--- a/drivers/media/rc/ir-hix5hd2.c
+++ b/drivers/media/rc/ir-hix5hd2.c
@@ -37,10 +37,13 @@
#define INT_CLR_RCV BIT(16)
#define INT_CLR_RCVTIMEOUT (BIT(16) | BIT(17))
-#define IR_CLK 0x48
#define IR_CLK_ENABLE BIT(4)
#define IR_CLK_RESET BIT(5)
+/* IR_ENABLE register bits */
+#define IR_ENABLE_EN BIT(0)
+#define IR_ENABLE_EN_EXTRA BIT(8)
+
#define IR_CFG_WIDTH_MASK 0xffff
#define IR_CFG_WIDTH_SHIFT 16
#define IR_CFG_FORMAT_MASK 0x3
@@ -58,6 +61,23 @@
#define IR_HIX5HD2_NAME "hix5hd2-ir"
+/* Need to set extra bit for enabling IR */
+#define HIX5HD2_FLAG_EXTRA_ENABLE BIT(0)
+
+struct hix5hd2_soc_data {
+ u32 clk_reg;
+ u32 flags;
+};
+
+static const struct hix5hd2_soc_data hix5hd2_data = {
+ .clk_reg = 0x48,
+};
+
+static const struct hix5hd2_soc_data hi3796cv300_data = {
+ .clk_reg = 0x60,
+ .flags = HIX5HD2_FLAG_EXTRA_ENABLE,
+};
+
struct hix5hd2_ir_priv {
int irq;
void __iomem *base;
@@ -66,15 +86,17 @@
struct regmap *regmap;
struct clk *clock;
unsigned long rate;
+ const struct hix5hd2_soc_data *socdata;
};
-static int hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, bool on)
+static int hix5hd2_ir_clk_enable(struct hix5hd2_ir_priv *dev, bool on)
{
+ u32 clk_reg = dev->socdata->clk_reg;
u32 val;
int ret = 0;
if (dev->regmap) {
- regmap_read(dev->regmap, IR_CLK, &val);
+ regmap_read(dev->regmap, clk_reg, &val);
if (on) {
val &= ~IR_CLK_RESET;
val |= IR_CLK_ENABLE;
@@ -82,7 +104,7 @@
val &= ~IR_CLK_ENABLE;
val |= IR_CLK_RESET;
}
- regmap_write(dev->regmap, IR_CLK, val);
+ regmap_write(dev->regmap, clk_reg, val);
} else {
if (on)
ret = clk_prepare_enable(dev->clock);
@@ -92,12 +114,23 @@
return ret;
}
+static inline void hix5hd2_ir_enable(struct hix5hd2_ir_priv *priv)
+{
+ u32 val = IR_ENABLE_EN;
+
+ if (priv->socdata->flags & HIX5HD2_FLAG_EXTRA_ENABLE)
+ val |= IR_ENABLE_EN_EXTRA;
+
+ writel_relaxed(val, priv->base + IR_ENABLE);
+}
+
static int hix5hd2_ir_config(struct hix5hd2_ir_priv *priv)
{
int timeout = 10000;
u32 val, rate;
- writel_relaxed(0x01, priv->base + IR_ENABLE);
+ hix5hd2_ir_enable(priv);
+
while (readl_relaxed(priv->base + IR_BUSY)) {
if (timeout--) {
udelay(1);
@@ -128,13 +161,13 @@
struct hix5hd2_ir_priv *priv = rdev->priv;
int ret;
- ret = hix5hd2_ir_enable(priv, true);
+ ret = hix5hd2_ir_clk_enable(priv, true);
if (ret)
return ret;
ret = hix5hd2_ir_config(priv);
if (ret) {
- hix5hd2_ir_enable(priv, false);
+ hix5hd2_ir_clk_enable(priv, false);
return ret;
}
return 0;
@@ -144,7 +177,7 @@
{
struct hix5hd2_ir_priv *priv = rdev->priv;
- hix5hd2_ir_enable(priv, false);
+ hix5hd2_ir_clk_enable(priv, false);
}
static irqreturn_t hix5hd2_ir_rx_interrupt(int irq, void *data)
@@ -181,12 +214,12 @@
data_h = ((symb_val >> 16) & 0xffff) * 10;
symb_time = (data_l + data_h) / 10;
- ev.duration = US_TO_NS(data_l);
+ ev.duration = data_l;
ev.pulse = true;
ir_raw_event_store(priv->rdev, &ev);
if (symb_time < IR_CFG_SYMBOL_MAXWIDTH) {
- ev.duration = US_TO_NS(data_h);
+ ev.duration = data_h;
ev.pulse = false;
ir_raw_event_store(priv->rdev, &ev);
} else {
@@ -205,6 +238,13 @@
return IRQ_HANDLED;
}
+static const struct of_device_id hix5hd2_ir_table[] = {
+ { .compatible = "hisilicon,hix5hd2-ir", &hix5hd2_data, },
+ { .compatible = "hisilicon,hi3796cv300-ir", &hi3796cv300_data, },
+ {},
+};
+MODULE_DEVICE_TABLE(of, hix5hd2_ir_table);
+
static int hix5hd2_ir_probe(struct platform_device *pdev)
{
struct rc_dev *rdev;
@@ -212,6 +252,7 @@
struct resource *res;
struct hix5hd2_ir_priv *priv;
struct device_node *node = pdev->dev.of_node;
+ const struct of_device_id *of_id;
const char *map_name;
int ret;
@@ -219,6 +260,13 @@
if (!priv)
return -ENOMEM;
+ of_id = of_match_device(hix5hd2_ir_table, dev);
+ if (!of_id) {
+ dev_err(dev, "Unable to initialize IR data\n");
+ return -ENODEV;
+ }
+ priv->socdata = of_id->data;
+
priv->regmap = syscon_regmap_lookup_by_phandle(node,
"hisilicon,power-syscon");
if (IS_ERR(priv->regmap)) {
@@ -263,8 +311,8 @@
rdev->input_id.vendor = 0x0001;
rdev->input_id.product = 0x0001;
rdev->input_id.version = 0x0100;
- rdev->rx_resolution = US_TO_NS(10);
- rdev->timeout = US_TO_NS(IR_CFG_SYMBOL_MAXWIDTH * 10);
+ rdev->rx_resolution = 10;
+ rdev->timeout = IR_CFG_SYMBOL_MAXWIDTH * 10;
ret = rc_register_device(rdev);
if (ret < 0)
@@ -309,7 +357,7 @@
struct hix5hd2_ir_priv *priv = dev_get_drvdata(dev);
clk_disable_unprepare(priv->clock);
- hix5hd2_ir_enable(priv, false);
+ hix5hd2_ir_clk_enable(priv, false);
return 0;
}
@@ -319,17 +367,18 @@
struct hix5hd2_ir_priv *priv = dev_get_drvdata(dev);
int ret;
- ret = hix5hd2_ir_enable(priv, true);
+ ret = hix5hd2_ir_clk_enable(priv, true);
if (ret)
return ret;
ret = clk_prepare_enable(priv->clock);
if (ret) {
- hix5hd2_ir_enable(priv, false);
+ hix5hd2_ir_clk_enable(priv, false);
return ret;
}
- writel_relaxed(0x01, priv->base + IR_ENABLE);
+ hix5hd2_ir_enable(priv);
+
writel_relaxed(0x00, priv->base + IR_INTM);
writel_relaxed(0xff, priv->base + IR_INTC);
writel_relaxed(0x01, priv->base + IR_START);
@@ -341,12 +390,6 @@
static SIMPLE_DEV_PM_OPS(hix5hd2_ir_pm_ops, hix5hd2_ir_suspend,
hix5hd2_ir_resume);
-static const struct of_device_id hix5hd2_ir_table[] = {
- { .compatible = "hisilicon,hix5hd2-ir", },
- {},
-};
-MODULE_DEVICE_TABLE(of, hix5hd2_ir_table);
-
static struct platform_driver hix5hd2_ir_driver = {
.driver = {
.name = IR_HIX5HD2_NAME,
diff --git a/drivers/media/rc/ir-imon-decoder.c b/drivers/media/rc/ir-imon-decoder.c
index a0efe26..41dbbef 100644
--- a/drivers/media/rc/ir-imon-decoder.c
+++ b/drivers/media/rc/ir-imon-decoder.c
@@ -8,7 +8,7 @@
#include <linux/module.h>
#include "rc-core-priv.h"
-#define IMON_UNIT 415662 /* ns */
+#define IMON_UNIT 416 /* us */
#define IMON_BITS 30
#define IMON_CHKBITS (BIT(30) | BIT(25) | BIT(24) | BIT(22) | \
BIT(21) | BIT(20) | BIT(19) | BIT(18) | \
@@ -102,8 +102,7 @@
dev_dbg(&dev->dev,
"iMON decode started at state %d bitno %d (%uus %s)\n",
- data->state, data->count, TO_US(ev.duration),
- TO_STR(ev.pulse));
+ data->state, data->count, ev.duration, TO_STR(ev.pulse));
/*
* Since iMON protocol is a series of bits, if at any point
@@ -116,7 +115,7 @@
* we're at a new scancode.
*/
if (data->state == STATE_ERROR) {
- if (!ev.pulse && ev.duration > MS_TO_NS(10))
+ if (!ev.pulse && ev.duration > MS_TO_US(10))
data->state = STATE_INACTIVE;
return 0;
}
@@ -169,8 +168,7 @@
err_out:
dev_dbg(&dev->dev,
"iMON decode failed at state %d bitno %d (%uus %s)\n",
- data->state, data->count, TO_US(ev.duration),
- TO_STR(ev.pulse));
+ data->state, data->count, ev.duration, TO_STR(ev.pulse));
data->state = STATE_ERROR;
diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c
index 864d9e3..470f2e1 100644
--- a/drivers/media/rc/ir-jvc-decoder.c
+++ b/drivers/media/rc/ir-jvc-decoder.c
@@ -9,7 +9,7 @@
#include "rc-core-priv.h"
#define JVC_NBITS 16 /* dev(8) + func(8) */
-#define JVC_UNIT 525000 /* ns */
+#define JVC_UNIT 525 /* us */
#define JVC_HEADER_PULSE (16 * JVC_UNIT) /* lack of header -> repeat */
#define JVC_HEADER_SPACE (8 * JVC_UNIT)
#define JVC_BIT_PULSE (1 * JVC_UNIT)
@@ -49,7 +49,7 @@
goto out;
dev_dbg(&dev->dev, "JVC decode started at state %d (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
again:
switch (data->state) {
@@ -157,7 +157,7 @@
out:
dev_dbg(&dev->dev, "JVC decode failed at state %d (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c
index cfe837f..1524dc0 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -21,7 +21,7 @@
* input device for the remote, rather than the keyboard/mouse one.
*/
-#define MCIR2_UNIT 333333 /* ns */
+#define MCIR2_UNIT 333 /* us */
#define MCIR2_HEADER_NBITS 5
#define MCIR2_MOUSE_NBITS 29
#define MCIR2_KEYBOARD_NBITS 32
@@ -231,7 +231,7 @@
again:
dev_dbg(&dev->dev, "started at state %i (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
if (!geq_margin(ev.duration, MCIR2_UNIT, MCIR2_UNIT / 2))
return 0;
@@ -320,7 +320,7 @@
data->body);
spin_lock(&data->keylock);
if (scancode) {
- delay = nsecs_to_jiffies(dev->timeout) +
+ delay = usecs_to_jiffies(dev->timeout) +
msecs_to_jiffies(100);
mod_timer(&data->rx_timeout, jiffies + delay);
} else {
@@ -344,7 +344,7 @@
}
lsc.scancode = scancode;
- ir_lirc_scancode_event(dev, &lsc);
+ lirc_scancode_event(dev, &lsc);
data->state = STATE_INACTIVE;
input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
input_sync(dev->input_dev);
@@ -353,7 +353,7 @@
out:
dev_dbg(&dev->dev, "failed at state %i (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 6a8973a..b4c3e4b 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -8,7 +8,7 @@
#include "rc-core-priv.h"
#define NEC_NBITS 32
-#define NEC_UNIT 562500 /* ns */
+#define NEC_UNIT 563 /* us */
#define NEC_HEADER_PULSE (16 * NEC_UNIT)
#define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */
#define NEC_HEADER_SPACE (8 * NEC_UNIT)
@@ -50,7 +50,7 @@
}
dev_dbg(&dev->dev, "NEC decode started at state %d (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
switch (data->state) {
@@ -163,7 +163,7 @@
}
dev_dbg(&dev->dev, "NEC decode failed at count %d state %d (%uus %s)\n",
- data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->count, data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c
index 6362465..d58b622 100644
--- a/drivers/media/rc/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -16,7 +16,7 @@
#define RC5_SZ_NBITS 15
#define RC5X_NBITS 20
#define CHECK_RC5X_NBITS 8
-#define RC5_UNIT 888888 /* ns */
+#define RC5_UNIT 889 /* us */
#define RC5_BIT_START (1 * RC5_UNIT)
#define RC5_BIT_END (1 * RC5_UNIT)
#define RC5X_SPACE (4 * RC5_UNIT)
@@ -55,7 +55,7 @@
again:
dev_dbg(&dev->dev, "RC5(x/sz) decode started at state %i (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
return 0;
@@ -164,7 +164,7 @@
out:
dev_dbg(&dev->dev, "RC5(x/sz) decode failed at state %i count %d (%uus %s)\n",
- data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, data->count, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c
index 95727ca..0657ad5 100644
--- a/drivers/media/rc/ir-rc6-decoder.c
+++ b/drivers/media/rc/ir-rc6-decoder.c
@@ -15,7 +15,7 @@
* RC6-6A-32 (MCE version with toggle bit in body)
*/
-#define RC6_UNIT 444444 /* nanosecs */
+#define RC6_UNIT 444 /* microseconds */
#define RC6_HEADER_NBITS 4 /* not including toggle bit */
#define RC6_0_NBITS 16
#define RC6_6A_32_NBITS 32
@@ -64,7 +64,7 @@
case 6:
if (!data->toggle)
return RC6_MODE_6A;
- /* fall through */
+ fallthrough;
default:
return RC6_MODE_UNKNOWN;
}
@@ -95,7 +95,7 @@
again:
dev_dbg(&dev->dev, "RC6 decode started at state %i (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
return 0;
@@ -270,7 +270,7 @@
out:
dev_dbg(&dev->dev, "RC6 decode failed at state %i (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir-rcmm-decoder.c b/drivers/media/rc/ir-rcmm-decoder.c
index 64fb65a..fd9ec69 100644
--- a/drivers/media/rc/ir-rcmm-decoder.c
+++ b/drivers/media/rc/ir-rcmm-decoder.c
@@ -6,12 +6,12 @@
#include "rc-core-priv.h"
#include <linux/module.h>
-#define RCMM_UNIT 166667 /* nanosecs */
-#define RCMM_PREFIX_PULSE 416666 /* 166666.666666666*2.5 */
-#define RCMM_PULSE_0 277777 /* 166666.666666666*(1+2/3) */
-#define RCMM_PULSE_1 444444 /* 166666.666666666*(2+2/3) */
-#define RCMM_PULSE_2 611111 /* 166666.666666666*(3+2/3) */
-#define RCMM_PULSE_3 777778 /* 166666.666666666*(4+2/3) */
+#define RCMM_UNIT 166 /* microseconds */
+#define RCMM_PREFIX_PULSE 417 /* 166.666666666666*2.5 */
+#define RCMM_PULSE_0 278 /* 166.666666666666*(1+2/3) */
+#define RCMM_PULSE_1 444 /* 166.666666666666*(2+2/3) */
+#define RCMM_PULSE_2 611 /* 166.666666666666*(3+2/3) */
+#define RCMM_PULSE_3 778 /* 166.666666666666*(4+2/3) */
enum rcmm_state {
STATE_INACTIVE,
@@ -64,8 +64,8 @@
int value;
if (!(dev->enabled_protocols & (RC_PROTO_BIT_RCMM32 |
- RC_PROTO_BIT_RCMM24 |
- RC_PROTO_BIT_RCMM12)))
+ RC_PROTO_BIT_RCMM24 |
+ RC_PROTO_BIT_RCMM12)))
return 0;
if (!is_timing_event(ev)) {
@@ -79,7 +79,7 @@
if (!ev.pulse)
break;
- if (!eq_margin(ev.duration, RCMM_PREFIX_PULSE, RCMM_UNIT / 2))
+ if (!eq_margin(ev.duration, RCMM_PREFIX_PULSE, RCMM_UNIT))
break;
data->state = STATE_LOW;
@@ -91,7 +91,7 @@
if (ev.pulse)
break;
- if (!eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT / 2))
+ if (!eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT))
break;
data->state = STATE_BUMP;
@@ -164,6 +164,8 @@
break;
}
+ dev_dbg(&dev->dev, "RC-MM decode failed at count %d state %d (%uus %s)\n",
+ data->count, data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c
index 8574eda..a0d9c02 100644
--- a/drivers/media/rc/ir-rx51.c
+++ b/drivers/media/rc/ir-rx51.c
@@ -241,7 +241,7 @@
}
/* Use default, in case userspace does not set the carrier */
- ir_rx51.freq = DIV_ROUND_CLOSEST(pwm_get_period(pwm), NSEC_PER_SEC);
+ ir_rx51.freq = DIV_ROUND_CLOSEST_ULL(pwm_get_period(pwm), NSEC_PER_SEC);
pwm_put(pwm);
hrtimer_init(&ir_rx51.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c
index dd6ee1e..bfc181b 100644
--- a/drivers/media/rc/ir-sanyo-decoder.c
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -17,7 +17,7 @@
#include "rc-core-priv.h"
#define SANYO_NBITS (13+13+8+8)
-#define SANYO_UNIT 562500 /* ns */
+#define SANYO_UNIT 563 /* us */
#define SANYO_HEADER_PULSE (16 * SANYO_UNIT)
#define SANYO_HEADER_SPACE (8 * SANYO_UNIT)
#define SANYO_BIT_PULSE (1 * SANYO_UNIT)
@@ -59,7 +59,7 @@
}
dev_dbg(&dev->dev, "SANYO decode started at state %d (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
switch (data->state) {
@@ -158,7 +158,7 @@
}
dev_dbg(&dev->dev, "SANYO decode failed at count %d state %d (%uus %s)\n",
- data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->count, data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c
index 37fab09..d09c38c 100644
--- a/drivers/media/rc/ir-sharp-decoder.c
+++ b/drivers/media/rc/ir-sharp-decoder.c
@@ -12,7 +12,7 @@
#include "rc-core-priv.h"
#define SHARP_NBITS 15
-#define SHARP_UNIT 40000 /* ns */
+#define SHARP_UNIT 40 /* us */
#define SHARP_BIT_PULSE (8 * SHARP_UNIT) /* 320us */
#define SHARP_BIT_0_PERIOD (25 * SHARP_UNIT) /* 1ms (680us space) */
#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680ms space) */
@@ -47,7 +47,7 @@
}
dev_dbg(&dev->dev, "Sharp decode started at state %d (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
switch (data->state) {
@@ -159,7 +159,7 @@
}
dev_dbg(&dev->dev, "Sharp decode failed at count %d state %d (%uus %s)\n",
- data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->count, data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c
index 9fa58d9..d760d52 100644
--- a/drivers/media/rc/ir-sony-decoder.c
+++ b/drivers/media/rc/ir-sony-decoder.c
@@ -8,7 +8,7 @@
#include <linux/module.h>
#include "rc-core-priv.h"
-#define SONY_UNIT 600000 /* ns */
+#define SONY_UNIT 600 /* us */
#define SONY_HEADER_PULSE (4 * SONY_UNIT)
#define SONY_HEADER_SPACE (1 * SONY_UNIT)
#define SONY_BIT_0_PULSE (1 * SONY_UNIT)
@@ -48,7 +48,7 @@
goto out;
dev_dbg(&dev->dev, "Sony decode started at state %d (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
switch (data->state) {
@@ -102,7 +102,7 @@
}
data->state = STATE_FINISHED;
- /* Fall through */
+ fallthrough;
case STATE_FINISHED:
if (ev.pulse)
@@ -154,7 +154,7 @@
out:
dev_dbg(&dev->dev, "Sony decode failed at state %d (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
diff --git a/drivers/media/rc/ir-xmp-decoder.c b/drivers/media/rc/ir-xmp-decoder.c
index 74a1d30..ff94f48 100644
--- a/drivers/media/rc/ir-xmp-decoder.c
+++ b/drivers/media/rc/ir-xmp-decoder.c
@@ -12,11 +12,12 @@
#include <linux/module.h>
#include "rc-core-priv.h"
-#define XMP_UNIT 136000 /* ns */
-#define XMP_LEADER 210000 /* ns */
-#define XMP_NIBBLE_PREFIX 760000 /* ns */
-#define XMP_HALFFRAME_SPACE 13800000 /* ns */
-#define XMP_TRAILER_SPACE 20000000 /* should be 80ms but not all dureation supliers can go that high */
+#define XMP_UNIT 136 /* us */
+#define XMP_LEADER 210 /* us */
+#define XMP_NIBBLE_PREFIX 760 /* us */
+#define XMP_HALFFRAME_SPACE 13800 /* us */
+/* should be 80ms but not all duration supliers can go that high */
+#define XMP_TRAILER_SPACE 20000
enum xmp_state {
STATE_INACTIVE,
@@ -42,7 +43,7 @@
}
dev_dbg(&dev->dev, "XMP decode started at state %d %d (%uus %s)\n",
- data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state, data->count, ev.duration, TO_STR(ev.pulse));
switch (data->state) {
@@ -166,7 +167,7 @@
} else if (geq_margin(ev.duration, XMP_NIBBLE_PREFIX, XMP_UNIT)) {
/* store nibble raw data, decode after trailer */
if (data->count == 16) {
- dev_dbg(&dev->dev, "to many pulses (%d) ignoring: %u\n",
+ dev_dbg(&dev->dev, "too many pulses (%d) ignoring: %u\n",
data->count, ev.duration);
data->state = STATE_INACTIVE;
return -EINVAL;
@@ -183,7 +184,7 @@
}
dev_dbg(&dev->dev, "XMP decode failed at count %d state %d (%uus %s)\n",
- data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->count, data->state, ev.duration, TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c
new file mode 100644
index 0000000..1aa7989
--- /dev/null
+++ b/drivers/media/rc/ir_toy.c
@@ -0,0 +1,529 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Infrared Toy and IR Droid RC core driver
+ *
+ * Copyright (C) 2020 Sean Young <sean@mess.org>
+
+ * This driver is based on the lirc driver which can be found here:
+ * https://sourceforge.net/p/lirc/git/ci/master/tree/plugins/irtoy.c
+ * Copyright (C) 2011 Peter Kooiman <pkooiman@gmail.com>
+ */
+
+#include <asm/unaligned.h>
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/usb/input.h>
+
+#include <media/rc-core.h>
+
+static const u8 COMMAND_VERSION[] = { 'v' };
+// End transmit and repeat reset command so we exit sump mode
+static const u8 COMMAND_RESET[] = { 0xff, 0xff, 0, 0, 0, 0, 0 };
+static const u8 COMMAND_SMODE_ENTER[] = { 's' };
+static const u8 COMMAND_SMODE_EXIT[] = { 0 };
+static const u8 COMMAND_TXSTART[] = { 0x26, 0x24, 0x25, 0x03 };
+
+#define REPLY_XMITCOUNT 't'
+#define REPLY_XMITSUCCESS 'C'
+#define REPLY_VERSION 'V'
+#define REPLY_SAMPLEMODEPROTO 'S'
+
+#define TIMEOUT 500
+
+#define LEN_XMITRES 3
+#define LEN_VERSION 4
+#define LEN_SAMPLEMODEPROTO 3
+
+#define MIN_FW_VERSION 20
+#define UNIT_US 21
+#define MAX_TIMEOUT_US (UNIT_US * U16_MAX)
+
+#define MAX_PACKET 64
+
+enum state {
+ STATE_IRDATA,
+ STATE_RESET,
+ STATE_COMMAND,
+ STATE_TX,
+};
+
+struct irtoy {
+ struct device *dev;
+ struct usb_device *usbdev;
+
+ struct rc_dev *rc;
+ struct urb *urb_in, *urb_out;
+
+ u8 *in;
+ u8 *out;
+ struct completion command_done;
+
+ bool pulse;
+ enum state state;
+
+ void *tx_buf;
+ uint tx_len;
+
+ uint emitted;
+ uint hw_version;
+ uint sw_version;
+ uint proto_version;
+
+ char phys[64];
+};
+
+static void irtoy_response(struct irtoy *irtoy, u32 len)
+{
+ switch (irtoy->state) {
+ case STATE_COMMAND:
+ if (len == LEN_VERSION && irtoy->in[0] == REPLY_VERSION) {
+ uint version;
+
+ irtoy->in[LEN_VERSION] = 0;
+
+ if (kstrtouint(irtoy->in + 1, 10, &version)) {
+ dev_err(irtoy->dev, "invalid version %*phN. Please make sure you are using firmware v20 or higher",
+ LEN_VERSION, irtoy->in);
+ break;
+ }
+
+ dev_dbg(irtoy->dev, "version %s\n", irtoy->in);
+
+ irtoy->hw_version = version / 100;
+ irtoy->sw_version = version % 100;
+
+ irtoy->state = STATE_IRDATA;
+ complete(&irtoy->command_done);
+ } else if (len == LEN_SAMPLEMODEPROTO &&
+ irtoy->in[0] == REPLY_SAMPLEMODEPROTO) {
+ uint version;
+
+ irtoy->in[LEN_SAMPLEMODEPROTO] = 0;
+
+ if (kstrtouint(irtoy->in + 1, 10, &version)) {
+ dev_err(irtoy->dev, "invalid sample mode response %*phN",
+ LEN_SAMPLEMODEPROTO, irtoy->in);
+ return;
+ }
+
+ dev_dbg(irtoy->dev, "protocol %s\n", irtoy->in);
+
+ irtoy->proto_version = version;
+
+ irtoy->state = STATE_IRDATA;
+ complete(&irtoy->command_done);
+ } else {
+ dev_err(irtoy->dev, "unexpected response to command: %*phN\n",
+ len, irtoy->in);
+ }
+ break;
+ case STATE_IRDATA: {
+ struct ir_raw_event rawir = { .pulse = irtoy->pulse };
+ __be16 *in = (__be16 *)irtoy->in;
+ int i;
+
+ for (i = 0; i < len / sizeof(__be16); i++) {
+ u16 v = be16_to_cpu(in[i]);
+
+ if (v == 0xffff) {
+ rawir.pulse = false;
+ } else {
+ rawir.duration = v * UNIT_US;
+ ir_raw_event_store_with_timeout(irtoy->rc,
+ &rawir);
+ }
+
+ rawir.pulse = !rawir.pulse;
+ }
+
+ irtoy->pulse = rawir.pulse;
+
+ ir_raw_event_handle(irtoy->rc);
+ break;
+ }
+ case STATE_TX:
+ if (irtoy->tx_len == 0) {
+ if (len == LEN_XMITRES &&
+ irtoy->in[0] == REPLY_XMITCOUNT) {
+ u16 emitted = get_unaligned_be16(irtoy->in + 1);
+
+ dev_dbg(irtoy->dev, "emitted:%u\n", emitted);
+
+ irtoy->emitted = emitted;
+ } else if (len == 1 &&
+ irtoy->in[0] == REPLY_XMITSUCCESS) {
+ irtoy->state = STATE_IRDATA;
+ complete(&irtoy->command_done);
+ }
+ } else {
+ // send next part of tx buffer
+ uint space = irtoy->in[0];
+ uint buf_len;
+ int err;
+
+ if (len != 1 || space > MAX_PACKET || space == 0) {
+ dev_err(irtoy->dev, "packet length expected: %*phN\n",
+ len, irtoy->in);
+ irtoy->state = STATE_IRDATA;
+ complete(&irtoy->command_done);
+ break;
+ }
+
+ buf_len = min(space, irtoy->tx_len);
+
+ dev_dbg(irtoy->dev, "remaining:%u sending:%u\n",
+ irtoy->tx_len, buf_len);
+
+ memcpy(irtoy->out, irtoy->tx_buf, buf_len);
+ irtoy->urb_out->transfer_buffer_length = buf_len;
+ err = usb_submit_urb(irtoy->urb_out, GFP_ATOMIC);
+ if (err != 0) {
+ dev_err(irtoy->dev, "fail to submit tx buf urb: %d\n",
+ err);
+ irtoy->state = STATE_IRDATA;
+ complete(&irtoy->command_done);
+ break;
+ }
+
+ irtoy->tx_buf += buf_len;
+ irtoy->tx_len -= buf_len;
+ }
+ break;
+ case STATE_RESET:
+ dev_err(irtoy->dev, "unexpected response to reset: %*phN\n",
+ len, irtoy->in);
+ }
+}
+
+static void irtoy_out_callback(struct urb *urb)
+{
+ struct irtoy *irtoy = urb->context;
+
+ if (urb->status == 0) {
+ if (irtoy->state == STATE_RESET)
+ complete(&irtoy->command_done);
+ } else {
+ dev_warn(irtoy->dev, "out urb status: %d\n", urb->status);
+ }
+}
+
+static void irtoy_in_callback(struct urb *urb)
+{
+ struct irtoy *irtoy = urb->context;
+ int ret;
+
+ if (urb->status == 0)
+ irtoy_response(irtoy, urb->actual_length);
+ else
+ dev_dbg(irtoy->dev, "in urb status: %d\n", urb->status);
+
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret && ret != -ENODEV)
+ dev_warn(irtoy->dev, "failed to resubmit urb: %d\n", ret);
+}
+
+static int irtoy_command(struct irtoy *irtoy, const u8 *cmd, int cmd_len,
+ enum state state)
+{
+ int err;
+
+ init_completion(&irtoy->command_done);
+
+ irtoy->state = state;
+
+ memcpy(irtoy->out, cmd, cmd_len);
+ irtoy->urb_out->transfer_buffer_length = cmd_len;
+
+ err = usb_submit_urb(irtoy->urb_out, GFP_KERNEL);
+ if (err != 0)
+ return err;
+
+ if (!wait_for_completion_timeout(&irtoy->command_done,
+ msecs_to_jiffies(TIMEOUT))) {
+ usb_kill_urb(irtoy->urb_out);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int irtoy_setup(struct irtoy *irtoy)
+{
+ int err;
+
+ err = irtoy_command(irtoy, COMMAND_RESET, sizeof(COMMAND_RESET),
+ STATE_RESET);
+ if (err != 0) {
+ dev_err(irtoy->dev, "could not write reset command: %d\n",
+ err);
+ return err;
+ }
+
+ usleep_range(50, 50);
+
+ // get version
+ err = irtoy_command(irtoy, COMMAND_VERSION, sizeof(COMMAND_VERSION),
+ STATE_COMMAND);
+ if (err) {
+ dev_err(irtoy->dev, "could not write version command: %d\n",
+ err);
+ return err;
+ }
+
+ // enter sample mode
+ err = irtoy_command(irtoy, COMMAND_SMODE_ENTER,
+ sizeof(COMMAND_SMODE_ENTER), STATE_COMMAND);
+ if (err)
+ dev_err(irtoy->dev, "could not write sample command: %d\n",
+ err);
+
+ return err;
+}
+
+/*
+ * When sending IR, it is imperative that we send the IR data as quickly
+ * as possible to the device, so it does not run out of IR data and
+ * introduce gaps. Allocate the buffer here, and then feed the data from
+ * the urb callback handler.
+ */
+static int irtoy_tx(struct rc_dev *rc, uint *txbuf, uint count)
+{
+ struct irtoy *irtoy = rc->priv;
+ unsigned int i, size;
+ __be16 *buf;
+ int err;
+
+ size = sizeof(u16) * (count + 1);
+ buf = kmalloc(size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ for (i = 0; i < count; i++) {
+ u16 v = DIV_ROUND_CLOSEST(txbuf[i], UNIT_US);
+
+ if (!v)
+ v = 1;
+ buf[i] = cpu_to_be16(v);
+ }
+
+ buf[count] = cpu_to_be16(0xffff);
+
+ irtoy->tx_buf = buf;
+ irtoy->tx_len = size;
+ irtoy->emitted = 0;
+
+ // There is an issue where if the unit is receiving IR while the
+ // first TXSTART command is sent, the device might end up hanging
+ // with its led on. It does not respond to any command when this
+ // happens. To work around this, re-enter sample mode.
+ err = irtoy_command(irtoy, COMMAND_SMODE_EXIT,
+ sizeof(COMMAND_SMODE_EXIT), STATE_RESET);
+ if (err) {
+ dev_err(irtoy->dev, "exit sample mode: %d\n", err);
+ return err;
+ }
+
+ err = irtoy_command(irtoy, COMMAND_SMODE_ENTER,
+ sizeof(COMMAND_SMODE_ENTER), STATE_COMMAND);
+ if (err) {
+ dev_err(irtoy->dev, "enter sample mode: %d\n", err);
+ return err;
+ }
+
+ err = irtoy_command(irtoy, COMMAND_TXSTART, sizeof(COMMAND_TXSTART),
+ STATE_TX);
+ kfree(buf);
+
+ if (err) {
+ dev_err(irtoy->dev, "failed to send tx start command: %d\n",
+ err);
+ // not sure what state the device is in, reset it
+ irtoy_setup(irtoy);
+ return err;
+ }
+
+ if (size != irtoy->emitted) {
+ dev_err(irtoy->dev, "expected %u emitted, got %u\n", size,
+ irtoy->emitted);
+ // not sure what state the device is in, reset it
+ irtoy_setup(irtoy);
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static int irtoy_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_host_interface *idesc = intf->cur_altsetting;
+ struct usb_device *usbdev = interface_to_usbdev(intf);
+ struct usb_endpoint_descriptor *ep_in = NULL;
+ struct usb_endpoint_descriptor *ep_out = NULL;
+ struct usb_endpoint_descriptor *ep = NULL;
+ struct irtoy *irtoy;
+ struct rc_dev *rc;
+ struct urb *urb;
+ int i, pipe, err = -ENOMEM;
+
+ for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
+ ep = &idesc->endpoint[i].desc;
+
+ if (!ep_in && usb_endpoint_is_bulk_in(ep) &&
+ usb_endpoint_maxp(ep) == MAX_PACKET)
+ ep_in = ep;
+
+ if (!ep_out && usb_endpoint_is_bulk_out(ep) &&
+ usb_endpoint_maxp(ep) == MAX_PACKET)
+ ep_out = ep;
+ }
+
+ if (!ep_in || !ep_out) {
+ dev_err(&intf->dev, "required endpoints not found\n");
+ return -ENODEV;
+ }
+
+ irtoy = kzalloc(sizeof(*irtoy), GFP_KERNEL);
+ if (!irtoy)
+ return -ENOMEM;
+
+ irtoy->in = kmalloc(MAX_PACKET, GFP_KERNEL);
+ if (!irtoy->in)
+ goto free_irtoy;
+
+ irtoy->out = kmalloc(MAX_PACKET, GFP_KERNEL);
+ if (!irtoy->out)
+ goto free_irtoy;
+
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
+ if (!rc)
+ goto free_irtoy;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ goto free_rcdev;
+
+ pipe = usb_rcvbulkpipe(usbdev, ep_in->bEndpointAddress);
+ usb_fill_bulk_urb(urb, usbdev, pipe, irtoy->in, MAX_PACKET,
+ irtoy_in_callback, irtoy);
+ irtoy->urb_in = urb;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ goto free_rcdev;
+
+ pipe = usb_sndbulkpipe(usbdev, ep_out->bEndpointAddress);
+ usb_fill_bulk_urb(urb, usbdev, pipe, irtoy->out, MAX_PACKET,
+ irtoy_out_callback, irtoy);
+
+ irtoy->dev = &intf->dev;
+ irtoy->usbdev = usbdev;
+ irtoy->rc = rc;
+ irtoy->urb_out = urb;
+ irtoy->pulse = true;
+
+ err = usb_submit_urb(irtoy->urb_in, GFP_KERNEL);
+ if (err != 0) {
+ dev_err(irtoy->dev, "fail to submit in urb: %d\n", err);
+ return err;
+ }
+
+ err = irtoy_setup(irtoy);
+ if (err)
+ goto free_rcdev;
+
+ dev_info(irtoy->dev, "version: hardware %u, firmware %u, protocol %u",
+ irtoy->hw_version, irtoy->sw_version, irtoy->proto_version);
+
+ if (irtoy->sw_version < MIN_FW_VERSION) {
+ dev_err(irtoy->dev, "need firmware V%02u or higher",
+ MIN_FW_VERSION);
+ err = -ENODEV;
+ goto free_rcdev;
+ }
+
+ usb_make_path(usbdev, irtoy->phys, sizeof(irtoy->phys));
+
+ rc->device_name = "Infrared Toy";
+ rc->driver_name = KBUILD_MODNAME;
+ rc->input_phys = irtoy->phys;
+ usb_to_input_id(usbdev, &rc->input_id);
+ rc->dev.parent = &intf->dev;
+ rc->priv = irtoy;
+ rc->tx_ir = irtoy_tx;
+ rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
+ rc->map_name = RC_MAP_RC6_MCE;
+ rc->rx_resolution = UNIT_US;
+ rc->timeout = IR_DEFAULT_TIMEOUT;
+
+ /*
+ * end of transmission is detected by absence of a usb packet
+ * with more pulse/spaces. However, each usb packet sent can
+ * contain 32 pulse/spaces, which can be quite lengthy, so there
+ * can be a delay between usb packets. For example with nec there is a
+ * 17ms gap between packets.
+ *
+ * So, make timeout a largish minimum which works with most protocols.
+ */
+ rc->min_timeout = MS_TO_US(40);
+ rc->max_timeout = MAX_TIMEOUT_US;
+
+ err = rc_register_device(rc);
+ if (err)
+ goto free_rcdev;
+
+ usb_set_intfdata(intf, irtoy);
+
+ return 0;
+
+free_rcdev:
+ usb_kill_urb(irtoy->urb_out);
+ usb_free_urb(irtoy->urb_out);
+ usb_kill_urb(irtoy->urb_in);
+ usb_free_urb(irtoy->urb_in);
+ rc_free_device(rc);
+free_irtoy:
+ kfree(irtoy->in);
+ kfree(irtoy->out);
+ kfree(irtoy);
+ return err;
+}
+
+static void irtoy_disconnect(struct usb_interface *intf)
+{
+ struct irtoy *ir = usb_get_intfdata(intf);
+
+ rc_unregister_device(ir->rc);
+ usb_set_intfdata(intf, NULL);
+ usb_kill_urb(ir->urb_out);
+ usb_free_urb(ir->urb_out);
+ usb_kill_urb(ir->urb_in);
+ usb_free_urb(ir->urb_in);
+ kfree(ir->in);
+ kfree(ir->out);
+ kfree(ir);
+}
+
+static const struct usb_device_id irtoy_table[] = {
+ { USB_DEVICE_INTERFACE_CLASS(0x04d8, 0xfd08, USB_CLASS_CDC_DATA) },
+ { USB_DEVICE_INTERFACE_CLASS(0x04d8, 0xf58b, USB_CLASS_CDC_DATA) },
+ { }
+};
+
+static struct usb_driver irtoy_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = irtoy_probe,
+ .disconnect = irtoy_disconnect,
+ .id_table = irtoy_table,
+};
+
+module_usb_driver(irtoy_driver);
+
+MODULE_AUTHOR("Sean Young <sean@mess.org>");
+MODULE_DESCRIPTION("Infrared Toy and IR Droid driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(usb, irtoy_table);
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index 4b8aee3..fbe794c 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -176,14 +176,14 @@
if (next_one > 0) {
ev.pulse = true;
ev.duration =
- ITE_BITS_TO_NS(next_one, sample_period);
+ ITE_BITS_TO_US(next_one, sample_period);
ir_raw_event_store_with_filter(dev->rdev, &ev);
}
while (next_one < size) {
next_zero = find_next_zero_bit_le(ldata, size, next_one + 1);
ev.pulse = false;
- ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period);
+ ev.duration = ITE_BITS_TO_US(next_zero - next_one, sample_period);
ir_raw_event_store_with_filter(dev->rdev, &ev);
if (next_zero < size) {
@@ -193,7 +193,7 @@
next_zero + 1);
ev.pulse = true;
ev.duration =
- ITE_BITS_TO_NS(next_one - next_zero,
+ ITE_BITS_TO_US(next_one - next_zero,
sample_period);
ir_raw_event_store_with_filter
(dev->rdev, &ev);
@@ -283,7 +283,7 @@
}
/* check for the receive interrupt */
- if (iflags & ITE_IRQ_RX_FIFO) {
+ if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) {
/* read the FIFO bytes */
rx_bytes =
dev->params.get_rx_bytes(dev, rx_buf,
@@ -388,7 +388,7 @@
ite_dbg("%s called", __func__);
/* clear the array just in case */
- memset(last_sent, 0, ARRAY_SIZE(last_sent));
+ memset(last_sent, 0, sizeof(last_sent));
spin_lock_irqsave(&dev->lock, flags);
@@ -1557,13 +1557,13 @@
rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
/* FIFO threshold is 17 bytes, so 17 * 8 samples minimum */
rdev->min_timeout = 17 * 8 * ITE_BAUDRATE_DIVISOR *
- itdev->params.sample_period;
+ itdev->params.sample_period / 1000;
rdev->timeout = IR_DEFAULT_TIMEOUT;
rdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
- itdev->params.sample_period;
+ itdev->params.sample_period / 1000;
rdev->tx_resolution = ITE_BAUDRATE_DIVISOR *
- itdev->params.sample_period;
+ itdev->params.sample_period / 1000;
/* set up transmitter related values if needed */
if (itdev->params.hw_tx_capable) {
diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h
index f04c4b3..4954470 100644
--- a/drivers/media/rc/ite-cir.h
+++ b/drivers/media/rc/ite-cir.h
@@ -146,8 +146,8 @@
#define ITE_DEFAULT_CARRIER_FREQ 38000
/* convert bits to us */
-#define ITE_BITS_TO_NS(bits, sample_period) \
-((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period))
+#define ITE_BITS_TO_US(bits, sample_period) \
+((u32)((bits) * ITE_BAUDRATE_DIVISOR * (sample_period) / 1000))
/*
* n in RDCR produces a tolerance of +/- n * 6.25% around the center
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index d89dcc4..3581761 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -17,6 +17,7 @@
rc-avermedia-rm-ks.o \
rc-avertv-303.o \
rc-azurewave-ad-tu700.o \
+ rc-beelink-gs1.o \
rc-behold.o \
rc-behold-columbus.o \
rc-budget-ci-old.o \
@@ -113,6 +114,7 @@
rc-tt-1500.o \
rc-twinhan-dtv-cab-ci.o \
rc-twinhan1027.o \
+ rc-vega-s9x.o \
rc-videomate-m1f.o \
rc-videomate-s350.o \
rc-videomate-tv-pvr.o \
diff --git a/drivers/media/rc/keymaps/rc-beelink-gs1.c b/drivers/media/rc/keymaps/rc-beelink-gs1.c
new file mode 100644
index 0000000..cedbd5d
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-beelink-gs1.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2019 Clément Péron
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+ * Keymap for the Beelink GS1 remote control
+ */
+
+static struct rc_map_table beelink_gs1_table[] = {
+ /*
+ * TV Keys (Power, Learn and Volume)
+ * { 0x40400d, KEY_TV },
+ * { 0x80f1, KEY_TV },
+ * { 0x80f3, KEY_TV },
+ * { 0x80f4, KEY_TV },
+ */
+
+ { 0x8051, KEY_POWER },
+ { 0x804d, KEY_MUTE },
+ { 0x8040, KEY_CONFIG },
+
+ { 0x8026, KEY_UP },
+ { 0x8028, KEY_DOWN },
+ { 0x8025, KEY_LEFT },
+ { 0x8027, KEY_RIGHT },
+ { 0x800d, KEY_OK },
+
+ { 0x8053, KEY_HOME },
+ { 0x80bc, KEY_MEDIA },
+ { 0x801b, KEY_BACK },
+ { 0x8049, KEY_MENU },
+
+ { 0x804e, KEY_VOLUMEUP },
+ { 0x8056, KEY_VOLUMEDOWN },
+
+ { 0x8054, KEY_SUBTITLE }, /* Web */
+ { 0x8052, KEY_EPG }, /* Media */
+
+ { 0x8041, KEY_CHANNELUP },
+ { 0x8042, KEY_CHANNELDOWN },
+
+ { 0x8031, KEY_1 },
+ { 0x8032, KEY_2 },
+ { 0x8033, KEY_3 },
+
+ { 0x8034, KEY_4 },
+ { 0x8035, KEY_5 },
+ { 0x8036, KEY_6 },
+
+ { 0x8037, KEY_7 },
+ { 0x8038, KEY_8 },
+ { 0x8039, KEY_9 },
+
+ { 0x8044, KEY_DELETE },
+ { 0x8030, KEY_0 },
+ { 0x8058, KEY_MODE }, /* # Input Method */
+};
+
+static struct rc_map_list beelink_gs1_map = {
+ .map = {
+ .scan = beelink_gs1_table,
+ .size = ARRAY_SIZE(beelink_gs1_table),
+ .rc_proto = RC_PROTO_NEC,
+ .name = RC_MAP_BEELINK_GS1,
+ }
+};
+
+static int __init init_rc_map_beelink_gs1(void)
+{
+ return rc_map_register(&beelink_gs1_map);
+}
+
+static void __exit exit_rc_map_beelink_gs1(void)
+{
+ rc_map_unregister(&beelink_gs1_map);
+}
+
+module_init(init_rc_map_beelink_gs1)
+module_exit(exit_rc_map_beelink_gs1)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Clément Péron <peron.clem@gmail.com>");
diff --git a/drivers/media/rc/keymaps/rc-vega-s9x.c b/drivers/media/rc/keymaps/rc-vega-s9x.c
new file mode 100644
index 0000000..bf210c4
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-vega-s9x.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2019 Christian Hewitt <christianshewitt@gmail.com>
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+//
+// Keytable for the Tronsmart Vega S9x remote control
+//
+
+static struct rc_map_table vega_s9x[] = {
+ { 0x18, KEY_POWER },
+ { 0x17, KEY_MUTE }, // mouse
+
+ { 0x46, KEY_UP },
+ { 0x47, KEY_LEFT },
+ { 0x55, KEY_OK },
+ { 0x15, KEY_RIGHT },
+ { 0x16, KEY_DOWN },
+
+ { 0x06, KEY_HOME },
+ { 0x42, KEY_PLAYPAUSE},
+ { 0x40, KEY_BACK },
+
+ { 0x14, KEY_VOLUMEDOWN },
+ { 0x04, KEY_MENU },
+ { 0x10, KEY_VOLUMEUP },
+};
+
+static struct rc_map_list vega_s9x_map = {
+ .map = {
+ .scan = vega_s9x,
+ .size = ARRAY_SIZE(vega_s9x),
+ .rc_proto = RC_PROTO_NEC,
+ .name = RC_MAP_VEGA_S9X,
+ }
+};
+
+static int __init init_rc_map_vega_s9x(void)
+{
+ return rc_map_register(&vega_s9x_map);
+}
+
+static void __exit exit_rc_map_vega_s9x(void)
+{
+ rc_map_unregister(&vega_s9x_map);
+}
+
+module_init(init_rc_map_vega_s9x)
+module_exit(exit_rc_map_vega_s9x)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com");
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index f078f8a..220363b 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -30,12 +30,12 @@
static struct class *lirc_class;
/**
- * ir_lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace
+ * lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace
*
* @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*/
-void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
+void lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
{
unsigned long flags;
struct lirc_fh *fh;
@@ -67,17 +67,16 @@
dev->gap = true;
dev->gap_duration = ev.duration;
- sample = LIRC_TIMEOUT(ev.duration / 1000);
+ sample = LIRC_TIMEOUT(ev.duration);
dev_dbg(&dev->dev, "timeout report (duration: %d)\n", sample);
/* Normal sample */
} else {
if (dev->gap) {
- dev->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
+ dev->gap_duration += ktime_to_us(ktime_sub(ktime_get(),
dev->gap_start));
- /* Convert to ms and cap by LIRC_VALUE_MASK */
- do_div(dev->gap_duration, 1000);
+ /* Cap by LIRC_VALUE_MASK */
dev->gap_duration = min_t(u64, dev->gap_duration,
LIRC_VALUE_MASK);
@@ -89,10 +88,10 @@
dev->gap = false;
}
- sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
- LIRC_SPACE(ev.duration / 1000);
+ sample = ev.pulse ? LIRC_PULSE(ev.duration) :
+ LIRC_SPACE(ev.duration);
dev_dbg(&dev->dev, "delivering %uus %s to lirc_dev\n",
- TO_US(ev.duration), TO_STR(ev.pulse));
+ ev.duration, TO_STR(ev.pulse));
}
/*
@@ -112,12 +111,12 @@
}
/**
- * ir_lirc_scancode_event() - Send scancode data to lirc to be relayed to
+ * lirc_scancode_event() - Send scancode data to lirc to be relayed to
* userspace. This can be called in atomic context.
* @dev: the struct rc_dev descriptor of the device
* @lsc: the struct lirc_scancode describing the decoded scancode
*/
-void ir_lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc)
+void lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc)
{
unsigned long flags;
struct lirc_fh *fh;
@@ -131,9 +130,9 @@
}
spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
}
-EXPORT_SYMBOL_GPL(ir_lirc_scancode_event);
+EXPORT_SYMBOL_GPL(lirc_scancode_event);
-static int ir_lirc_open(struct inode *inode, struct file *file)
+static int lirc_open(struct inode *inode, struct file *file)
{
struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev,
lirc_cdev);
@@ -201,7 +200,7 @@
return retval;
}
-static int ir_lirc_close(struct inode *inode, struct file *file)
+static int lirc_close(struct inode *inode, struct file *file)
{
struct lirc_fh *fh = file->private_data;
struct rc_dev *dev = fh->rc;
@@ -223,8 +222,8 @@
return 0;
}
-static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
- size_t n, loff_t *ppos)
+static ssize_t lirc_transmit(struct file *file, const char __user *buf,
+ size_t n, loff_t *ppos)
{
struct lirc_fh *fh = file->private_data;
struct rc_dev *dev = fh->rc;
@@ -269,12 +268,7 @@
goto out_unlock;
}
- /*
- * The scancode field in lirc_scancode is 64-bit simply
- * to future-proof it, since there are IR protocols encode
- * use more than 32 bits. For now only 32-bit protocols
- * are supported.
- */
+ /* We only have encoders for 32-bit protocols. */
if (scan.scancode > U32_MAX ||
!rc_validate_scancode(scan.rc_proto, scan.scancode)) {
ret = -EINVAL;
@@ -301,8 +295,7 @@
}
for (i = 0; i < count; i++)
- /* Convert from NS to US */
- txbuf[i] = DIV_ROUND_UP(raw[i].duration, 1000);
+ txbuf[i] = raw[i].duration;
if (dev->s_tx_carrier) {
int carrier = ir_raw_encode_carrier(scan.rc_proto);
@@ -330,7 +323,7 @@
}
for (i = 0; i < count; i++) {
- if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) {
+ if (txbuf[i] > IR_MAX_DURATION - duration || !txbuf[i]) {
ret = -EINVAL;
goto out_kfree;
}
@@ -370,8 +363,7 @@
return ret;
}
-static long ir_lirc_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+static long lirc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct lirc_fh *fh = file->private_data;
struct rc_dev *dev = fh->rc;
@@ -522,7 +514,7 @@
if (!dev->rx_resolution)
ret = -ENOTTY;
else
- val = dev->rx_resolution / 1000;
+ val = dev->rx_resolution;
break;
case LIRC_SET_WIDEBAND_RECEIVER:
@@ -544,31 +536,26 @@
if (!dev->max_timeout)
ret = -ENOTTY;
else
- val = DIV_ROUND_UP(dev->min_timeout, 1000);
+ val = dev->min_timeout;
break;
case LIRC_GET_MAX_TIMEOUT:
if (!dev->max_timeout)
ret = -ENOTTY;
else
- val = dev->max_timeout / 1000;
+ val = dev->max_timeout;
break;
case LIRC_SET_REC_TIMEOUT:
if (!dev->max_timeout) {
ret = -ENOTTY;
- } else if (val > U32_MAX / 1000) {
- /* Check for multiply overflow */
- ret = -EINVAL;
} else {
- u32 tmp = val * 1000;
-
- if (tmp < dev->min_timeout || tmp > dev->max_timeout)
+ if (val < dev->min_timeout || val > dev->max_timeout)
ret = -EINVAL;
else if (dev->s_timeout)
- ret = dev->s_timeout(dev, tmp);
+ ret = dev->s_timeout(dev, val);
else
- dev->timeout = tmp;
+ dev->timeout = val;
}
break;
@@ -576,7 +563,7 @@
if (!dev->timeout)
ret = -ENOTTY;
else
- val = DIV_ROUND_UP(dev->timeout, 1000);
+ val = dev->timeout;
break;
case LIRC_SET_REC_TIMEOUT_REPORTS:
@@ -598,7 +585,7 @@
return ret;
}
-static __poll_t ir_lirc_poll(struct file *file, struct poll_table_struct *wait)
+static __poll_t lirc_poll(struct file *file, struct poll_table_struct *wait)
{
struct lirc_fh *fh = file->private_data;
struct rc_dev *rcdev = fh->rc;
@@ -621,8 +608,8 @@
return events;
}
-static ssize_t ir_lirc_read_mode2(struct file *file, char __user *buffer,
- size_t length)
+static ssize_t lirc_read_mode2(struct file *file, char __user *buffer,
+ size_t length)
{
struct lirc_fh *fh = file->private_data;
struct rc_dev *rcdev = fh->rc;
@@ -659,8 +646,8 @@
return copied;
}
-static ssize_t ir_lirc_read_scancode(struct file *file, char __user *buffer,
- size_t length)
+static ssize_t lirc_read_scancode(struct file *file, char __user *buffer,
+ size_t length)
{
struct lirc_fh *fh = file->private_data;
struct rc_dev *rcdev = fh->rc;
@@ -698,8 +685,8 @@
return copied;
}
-static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
- size_t length, loff_t *ppos)
+static ssize_t lirc_read(struct file *file, char __user *buffer, size_t length,
+ loff_t *ppos)
{
struct lirc_fh *fh = file->private_data;
struct rc_dev *rcdev = fh->rc;
@@ -711,22 +698,20 @@
return -ENODEV;
if (fh->rec_mode == LIRC_MODE_MODE2)
- return ir_lirc_read_mode2(file, buffer, length);
+ return lirc_read_mode2(file, buffer, length);
else /* LIRC_MODE_SCANCODE */
- return ir_lirc_read_scancode(file, buffer, length);
+ return lirc_read_scancode(file, buffer, length);
}
static const struct file_operations lirc_fops = {
.owner = THIS_MODULE,
- .write = ir_lirc_transmit_ir,
- .unlocked_ioctl = ir_lirc_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = ir_lirc_ioctl,
-#endif
- .read = ir_lirc_read,
- .poll = ir_lirc_poll,
- .open = ir_lirc_open,
- .release = ir_lirc_close,
+ .write = lirc_transmit,
+ .unlocked_ioctl = lirc_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
+ .read = lirc_read,
+ .poll = lirc_poll,
+ .open = lirc_open,
+ .release = lirc_close,
.llseek = no_llseek,
};
@@ -737,7 +722,7 @@
put_device(&rcdev->dev);
}
-int ir_lirc_register(struct rc_dev *dev)
+int lirc_register(struct rc_dev *dev)
{
const char *rx_type, *tx_type;
int err, minor;
@@ -791,7 +776,7 @@
return err;
}
-void ir_lirc_unregister(struct rc_dev *dev)
+void lirc_unregister(struct rc_dev *dev)
{
unsigned long flags;
struct lirc_fh *fh;
@@ -818,8 +803,7 @@
return PTR_ERR(lirc_class);
}
- retval = alloc_chrdev_region(&lirc_base_dev, 0, RC_DEV_MAX,
- "BaseRemoteCtl");
+ retval = alloc_chrdev_region(&lirc_base_dev, 0, RC_DEV_MAX, "lirc");
if (retval) {
class_destroy(lirc_class);
pr_err("alloc_chrdev_region failed\n");
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index c68e52c..dbb5a4f 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1077,7 +1077,7 @@
struct mceusb_dev *ir = dev->priv;
unsigned int units;
- units = DIV_ROUND_CLOSEST(timeout, US_TO_NS(MCE_TIME_UNIT));
+ units = DIV_ROUND_CLOSEST(timeout, MCE_TIME_UNIT);
cmdbuf[2] = units >> 8;
cmdbuf[3] = units;
@@ -1203,7 +1203,7 @@
switch (subcmd) {
/* 2-byte return value commands */
case MCE_RSP_EQIRTIMEOUT:
- ir->rc->timeout = US_TO_NS((*hi << 8 | *lo) * MCE_TIME_UNIT);
+ ir->rc->timeout = (*hi << 8 | *lo) * MCE_TIME_UNIT;
break;
case MCE_RSP_EQIRNUMPORTS:
ir->num_txports = *hi;
@@ -1298,9 +1298,9 @@
ir->pulse_tunit += rawir.duration;
ir->pulse_count++;
}
- rawir.duration *= US_TO_NS(MCE_TIME_UNIT);
+ rawir.duration *= MCE_TIME_UNIT;
- dev_dbg(ir->dev, "Storing %s %u ns (%02x)",
+ dev_dbg(ir->dev, "Storing %s %u us (%02x)",
rawir.pulse ? "pulse" : "space",
rawir.duration, ir->buf_in[i]);
@@ -1386,6 +1386,7 @@
case -ECONNRESET:
case -ENOENT:
case -EILSEQ:
+ case -EPROTO:
case -ESHUTDOWN:
usb_unlink_urb(urb);
return;
@@ -1429,7 +1430,7 @@
*/
ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
- data, USB_CTRL_MSG_SZ, HZ * 3);
+ data, USB_CTRL_MSG_SZ, 3000);
dev_dbg(dev, "set address - ret = %d", ret);
dev_dbg(dev, "set address - data[0] = %d, data[1] = %d",
data[0], data[1]);
@@ -1437,20 +1438,20 @@
/* set feature: bit rate 38400 bps */
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
- 0xc04e, 0x0000, NULL, 0, HZ * 3);
+ 0xc04e, 0x0000, NULL, 0, 3000);
dev_dbg(dev, "set feature - ret = %d", ret);
/* bRequest 4: set char length to 8 bits */
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
4, USB_TYPE_VENDOR,
- 0x0808, 0x0000, NULL, 0, HZ * 3);
+ 0x0808, 0x0000, NULL, 0, 3000);
dev_dbg(dev, "set char length - retB = %d", ret);
/* bRequest 2: set handshaking to use DTR/DSR */
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
2, USB_TYPE_VENDOR,
- 0x0000, 0x0100, NULL, 0, HZ * 3);
+ 0x0000, 0x0100, NULL, 0, 3000);
dev_dbg(dev, "set handshake - retC = %d", ret);
/* device resume */
@@ -1612,8 +1613,8 @@
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);
+ rc->min_timeout = MCE_TIME_UNIT;
+ rc->timeout = MS_TO_US(100);
if (!mceusb_model[ir->model].broken_irtimeout) {
rc->s_timeout = mceusb_set_timeout;
rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
@@ -1733,7 +1734,7 @@
goto mem_alloc_fail;
ir->pipe_in = pipe;
- ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in);
+ ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_KERNEL, &ir->dma_in);
if (!ir->buf_in)
goto buf_in_alloc_fail;
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index 51c6dd3..dad5595 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -86,7 +86,7 @@
duration = readl_relaxed(ir->reg + IR_DEC_REG1);
duration = FIELD_GET(REG1_TIME_IV_MASK, duration);
- rawir.duration = US_TO_NS(duration * MESON_TRATE);
+ rawir.duration = duration * MESON_TRATE;
status = readl_relaxed(ir->reg + IR_DEC_STATUS);
rawir.pulse = !!(status & STATUS_IR_DEC_IN);
@@ -133,7 +133,7 @@
map_name = of_get_property(node, "linux,rc-map-name", NULL);
ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
- ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
+ ir->rc->rx_resolution = MESON_TRATE;
ir->rc->min_timeout = 1;
ir->rc->timeout = IR_DEFAULT_TIMEOUT;
ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
index a0c94ab..65a136c 100644
--- a/drivers/media/rc/mtk-cir.c
+++ b/drivers/media/rc/mtk-cir.c
@@ -52,8 +52,8 @@
#define MTK_IR_END(v, p) ((v) == MTK_MAX_SAMPLES && (p) == 0)
/* Number of registers to record the pulse width */
#define MTK_CHKDATA_SZ 17
-/* Sample period in ns */
-#define MTK_IR_SAMPLE 46000
+/* Sample period in us */
+#define MTK_IR_SAMPLE 46
enum mtk_fields {
/* Register to setting software sampling period */
@@ -151,15 +151,12 @@
{
u32 val;
- /* Period of raw software sampling in ns */
- val = DIV_ROUND_CLOSEST(1000000000ul,
- clk_get_rate(ir->bus) / ir->data->div);
-
/*
* Period for software decoder used in the
* unit of raw software sampling
*/
- val = DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, val);
+ val = DIV_ROUND_CLOSEST(clk_get_rate(ir->bus),
+ USEC_PER_SEC * ir->data->div / MTK_IR_SAMPLE);
dev_dbg(ir->dev, "@pwm clk = \t%lu\n",
clk_get_rate(ir->bus) / ir->data->div);
@@ -412,7 +409,7 @@
mtk_irq_enable(ir, MTK_IRINT_EN);
dev_info(dev, "Initialized MT7623 IR driver, sample period = %dus\n",
- DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, 1000));
+ MTK_IR_SAMPLE);
return 0;
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 5c2cd8d..8a37f08 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -74,13 +74,6 @@
nvt_cr_write(nvt, tmp, reg);
}
-/* clear config register bit without changing other bits */
-static inline void nvt_clear_reg_bit(struct nvt_dev *nvt, u8 val, u8 reg)
-{
- u8 tmp = nvt_cr_read(nvt, reg) & ~val;
- nvt_cr_write(nvt, tmp, reg);
-}
-
/* enter extended function mode */
static inline int nvt_efm_enable(struct nvt_dev *nvt)
{
@@ -230,10 +223,10 @@
for (i = 0; i < fifo_len; i++) {
duration = nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY);
duration = (duration & BUF_LEN_MASK) * SAMPLE_PERIOD;
- buf_len += snprintf(buf + buf_len, PAGE_SIZE - buf_len,
+ buf_len += scnprintf(buf + buf_len, PAGE_SIZE - buf_len,
"%d ", duration);
}
- buf_len += snprintf(buf + buf_len, PAGE_SIZE - buf_len, "\n");
+ buf_len += scnprintf(buf + buf_len, PAGE_SIZE - buf_len, "\n");
spin_unlock_irqrestore(&nvt->lock, flags);
@@ -631,30 +624,6 @@
return carrier;
}
#endif
-/*
- * set carrier frequency
- *
- * set carrier on 2 registers: CP & CC
- * always set CP as 0x81
- * set CC by SPEC, CC = 3MHz/carrier - 1
- */
-static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier)
-{
- struct nvt_dev *nvt = dev->priv;
- u16 val;
-
- if (carrier == 0)
- return -EINVAL;
-
- nvt_cir_reg_write(nvt, 1, CIR_CP);
- val = 3000000 / (carrier) - 1;
- nvt_cir_reg_write(nvt, val & 0xff, CIR_CC);
-
- nvt_dbg("cp: 0x%x cc: 0x%x\n",
- nvt_cir_reg_read(nvt, CIR_CP), nvt_cir_reg_read(nvt, CIR_CC));
-
- return 0;
-}
static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev,
struct rc_scancode_filter *sc_filter)
@@ -684,8 +653,7 @@
/* Inspect the ir samples */
for (i = 0, count = 0; i < ret && count < WAKEUP_MAX_SIZE; ++i) {
- /* NS to US */
- val = DIV_ROUND_UP(raw[i].duration, 1000L) / SAMPLE_PERIOD;
+ val = raw[i].duration / SAMPLE_PERIOD;
/* Split too large values into several smaller ones */
while (val > 0 && count < WAKEUP_MAX_SIZE) {
@@ -752,8 +720,7 @@
sample = nvt->buf[i];
rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
- rawir.duration = US_TO_NS((sample & BUF_LEN_MASK)
- * SAMPLE_PERIOD);
+ rawir.duration = (sample & BUF_LEN_MASK) * SAMPLE_PERIOD;
nvt_dbg("Storing %s with duration %d",
rawir.pulse ? "pulse" : "space", rawir.duration);
@@ -1022,7 +989,6 @@
rdev->encode_wakeup = true;
rdev->open = nvt_open;
rdev->close = nvt_close;
- rdev->s_tx_carrier = nvt_set_tx_carrier;
rdev->s_wakeup_filter = nvt_ir_raw_set_wakeup_filter;
rdev->device_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
rdev->input_phys = "nuvoton/cir0";
@@ -1032,9 +998,9 @@
rdev->input_id.version = nvt->chip_minor;
rdev->driver_name = NVT_DRIVER_NAME;
rdev->map_name = RC_MAP_RC6_MCE;
- rdev->timeout = MS_TO_NS(100);
+ rdev->timeout = MS_TO_US(100);
/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
- rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
+ rdev->rx_resolution = CIR_SAMPLE_PERIOD;
#if 0
rdev->min_timeout = XYZ;
rdev->max_timeout = XYZ;
diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h
index 0cf301d..ed7d93b 100644
--- a/drivers/media/rc/nuvoton-cir.h
+++ b/drivers/media/rc/nuvoton-cir.h
@@ -94,7 +94,7 @@
#define CIR_IOREG_LENGTH 0x0f
/* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL */
-#define CIR_RX_LIMIT_COUNT (IR_DEFAULT_TIMEOUT / US_TO_NS(SAMPLE_PERIOD))
+#define CIR_RX_LIMIT_COUNT (IR_DEFAULT_TIMEOUT / SAMPLE_PERIOD)
/* CIR Regs */
#define CIR_IRCON 0x00
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 9f21b3e..62f032d 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -1,5 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
- * SPDX-License-Identifier: GPL-2.0
* Remote Controller core raw events header
*
* Copyright (C) 2010 by Mauro Carvalho Chehab
@@ -64,6 +64,7 @@
u32 bpf_sample;
struct bpf_prog_array __rcu *progs;
#endif
+#if IS_ENABLED(CONFIG_IR_NEC_DECODER)
struct nec_dec {
int state;
unsigned count;
@@ -71,12 +72,16 @@
bool is_nec_x;
bool necx_repeat;
} nec;
+#endif
+#if IS_ENABLED(CONFIG_IR_RC5_DECODER)
struct rc5_dec {
int state;
u32 bits;
unsigned count;
bool is_rc5x;
} rc5;
+#endif
+#if IS_ENABLED(CONFIG_IR_RC6_DECODER)
struct rc6_dec {
int state;
u8 header;
@@ -85,11 +90,15 @@
unsigned count;
unsigned wanted_bits;
} rc6;
+#endif
+#if IS_ENABLED(CONFIG_IR_SONY_DECODER)
struct sony_dec {
int state;
u32 bits;
unsigned count;
} sony;
+#endif
+#if IS_ENABLED(CONFIG_IR_JVC_DECODER)
struct jvc_dec {
int state;
u16 bits;
@@ -98,17 +107,23 @@
bool first;
bool toggle;
} jvc;
+#endif
+#if IS_ENABLED(CONFIG_IR_SANYO_DECODER)
struct sanyo_dec {
int state;
unsigned count;
u64 bits;
} sanyo;
+#endif
+#if IS_ENABLED(CONFIG_IR_SHARP_DECODER)
struct sharp_dec {
int state;
unsigned count;
u32 bits;
unsigned int pulse_len;
} sharp;
+#endif
+#if IS_ENABLED(CONFIG_IR_MCE_KBD_DECODER)
struct mce_kbd_dec {
/* locks key up timer */
spinlock_t keylock;
@@ -119,11 +134,15 @@
unsigned count;
unsigned wanted_bits;
} mce_kbd;
+#endif
+#if IS_ENABLED(CONFIG_IR_XMP_DECODER)
struct xmp_dec {
int state;
unsigned count;
u32 durations[16];
} xmp;
+#endif
+#if IS_ENABLED(CONFIG_IR_IMON_DECODER)
struct imon_dec {
int state;
int count;
@@ -131,11 +150,14 @@
unsigned int bits;
bool stick_keyboard;
} imon;
+#endif
+#if IS_ENABLED(CONFIG_IR_RCMM_DECODER)
struct rcmm_dec {
int state;
unsigned int count;
u32 bits;
} rcmm;
+#endif
};
/* Mutex for locking raw IR processing and handler change */
@@ -171,7 +193,6 @@
return !ev.carrier_report && !ev.reset;
}
-#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000)
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
/* functions for IR encoders */
@@ -300,20 +321,20 @@
#ifdef CONFIG_LIRC
int lirc_dev_init(void);
void lirc_dev_exit(void);
-void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev);
-void ir_lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc);
-int ir_lirc_register(struct rc_dev *dev);
-void ir_lirc_unregister(struct rc_dev *dev);
+void lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev);
+void lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc);
+int lirc_register(struct rc_dev *dev);
+void lirc_unregister(struct rc_dev *dev);
struct rc_dev *rc_dev_get_from_fd(int fd);
#else
static inline int lirc_dev_init(void) { return 0; }
static inline void lirc_dev_exit(void) {}
-static inline void ir_lirc_raw_event(struct rc_dev *dev,
- struct ir_raw_event ev) { }
-static inline void ir_lirc_scancode_event(struct rc_dev *dev,
- struct lirc_scancode *lsc) { }
-static inline int ir_lirc_register(struct rc_dev *dev) { return 0; }
-static inline void ir_lirc_unregister(struct rc_dev *dev) { }
+static inline void lirc_raw_event(struct rc_dev *dev,
+ struct ir_raw_event ev) { }
+static inline void lirc_scancode_event(struct rc_dev *dev,
+ struct lirc_scancode *lsc) { }
+static inline int lirc_register(struct rc_dev *dev) { return 0; }
+static inline void lirc_unregister(struct rc_dev *dev) { }
#endif
/*
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 39dd46b..c65bba4 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -42,7 +42,7 @@
if (dev->enabled_protocols &
handler->protocols || !handler->protocols)
handler->decode(dev, ev);
- ir_lirc_raw_event(dev, ev);
+ lirc_raw_event(dev, ev);
raw->prev_ev = ev;
}
mutex_unlock(&ir_raw_handler_lock);
@@ -77,7 +77,7 @@
return -EINVAL;
dev_dbg(&dev->dev, "sample: (%05dus %s)\n",
- TO_US(ev->duration), TO_STR(ev->pulse));
+ ev->duration, TO_STR(ev->pulse));
if (!kfifo_put(&dev->raw->kfifo, *ev)) {
dev_err(&dev->dev, "IR event FIFO is full!\n");
@@ -108,7 +108,7 @@
return -EINVAL;
now = ktime_get();
- ev.duration = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
+ ev.duration = ktime_to_us(ktime_sub(now, dev->raw->last_event));
ev.pulse = !pulse;
return ir_raw_event_store_with_timeout(dev, &ev);
@@ -275,7 +275,7 @@
if (timeout == 0)
timeout = IR_DEFAULT_TIMEOUT;
else
- timeout += MS_TO_NS(10);
+ timeout += MS_TO_US(10);
if (timeout < dev->min_timeout)
timeout = dev->min_timeout;
@@ -561,17 +561,17 @@
spin_lock_irqsave(&dev->raw->edge_spinlock, flags);
interval = ktime_sub(ktime_get(), dev->raw->last_event);
- if (ktime_to_ns(interval) >= dev->timeout) {
+ if (ktime_to_us(interval) >= dev->timeout) {
struct ir_raw_event ev = {
.timeout = true,
- .duration = ktime_to_ns(interval)
+ .duration = ktime_to_us(interval)
};
ir_raw_event_store(dev, &ev);
} else {
mod_timer(&dev->raw->edge_handle,
- jiffies + nsecs_to_jiffies(dev->timeout -
- ktime_to_ns(interval)));
+ jiffies + usecs_to_jiffies(dev->timeout -
+ ktime_to_us(interval)));
}
spin_unlock_irqrestore(&dev->raw->edge_spinlock, flags);
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index 13ab731..40ab66c 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -113,7 +113,7 @@
for (i = 0; i < count; i++) {
rawir.pulse = i % 2 ? false : true;
- rawir.duration = txbuf[i] * 1000;
+ rawir.duration = txbuf[i];
if (rawir.duration)
ir_raw_event_store_with_filter(dev, &rawir);
}
@@ -219,11 +219,11 @@
rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
rc->allowed_wakeup_protocols = RC_PROTO_BIT_ALL_IR_ENCODER;
rc->encode_wakeup = true;
- rc->timeout = 100 * 1000 * 1000; /* 100 ms */
+ rc->timeout = MS_TO_US(100); /* 100 ms */
rc->min_timeout = 1;
rc->max_timeout = UINT_MAX;
- rc->rx_resolution = 1000;
- rc->tx_resolution = 1000;
+ rc->rx_resolution = 1;
+ rc->tx_resolution = 1;
rc->s_tx_mask = loop_set_tx_mask;
rc->s_tx_carrier = loop_set_tx_carrier;
rc->s_tx_duty_cycle = loop_set_tx_duty_cycle;
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index ee80f38..8e88dc8 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -164,6 +164,41 @@
};
/**
+ * scancode_to_u64() - converts scancode in &struct input_keymap_entry
+ * @ke: keymap entry containing scancode to be converted.
+ * @scancode: pointer to the location where converted scancode should
+ * be stored.
+ *
+ * This function is a version of input_scancode_to_scalar specialized for
+ * rc-core.
+ */
+static int scancode_to_u64(const struct input_keymap_entry *ke, u64 *scancode)
+{
+ switch (ke->len) {
+ case 1:
+ *scancode = *((u8 *)ke->scancode);
+ break;
+
+ case 2:
+ *scancode = *((u16 *)ke->scancode);
+ break;
+
+ case 4:
+ *scancode = *((u32 *)ke->scancode);
+ break;
+
+ case 8:
+ *scancode = *((u64 *)ke->scancode);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
* ir_create_table() - initializes a scancode table
* @dev: the rc_dev device
* @rc_map: the rc_map to initialize
@@ -285,13 +320,13 @@
/* Did the user wish to remove the mapping? */
if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
- dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04x\n",
+ dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04llx\n",
index, rc_map->scan[index].scancode);
rc_map->len--;
memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
(rc_map->len - index) * sizeof(struct rc_map_table));
} else {
- dev_dbg(&dev->dev, "#%d: %s scan 0x%04x with key 0x%04x\n",
+ dev_dbg(&dev->dev, "#%d: %s scan 0x%04llx with key 0x%04x\n",
index,
old_keycode == KEY_RESERVED ? "New" : "Replacing",
rc_map->scan[index].scancode, new_keycode);
@@ -334,8 +369,7 @@
*/
static unsigned int ir_establish_scancode(struct rc_dev *dev,
struct rc_map *rc_map,
- unsigned int scancode,
- bool resize)
+ u64 scancode, bool resize)
{
unsigned int i;
@@ -394,7 +428,7 @@
struct rc_dev *rdev = input_get_drvdata(idev);
struct rc_map *rc_map = &rdev->rc_map;
unsigned int index;
- unsigned int scancode;
+ u64 scancode;
int retval = 0;
unsigned long flags;
@@ -407,7 +441,7 @@
goto out;
}
} else {
- retval = input_scancode_to_scalar(ke, &scancode);
+ retval = scancode_to_u64(ke, &scancode);
if (retval)
goto out;
@@ -434,8 +468,7 @@
*
* return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
*/
-static int ir_setkeytable(struct rc_dev *dev,
- const struct rc_map *from)
+static int ir_setkeytable(struct rc_dev *dev, const struct rc_map *from)
{
struct rc_map *rc_map = &dev->rc_map;
unsigned int i, index;
@@ -466,7 +499,7 @@
static int rc_map_cmp(const void *key, const void *elt)
{
- const unsigned int *scancode = key;
+ const u64 *scancode = key;
const struct rc_map_table *e = elt;
if (*scancode < e->scancode)
@@ -487,7 +520,7 @@
* return: index in the table, -1U if not found
*/
static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
- unsigned int scancode)
+ u64 scancode)
{
struct rc_map_table *res;
@@ -516,7 +549,7 @@
struct rc_map_table *entry;
unsigned long flags;
unsigned int index;
- unsigned int scancode;
+ u64 scancode;
int retval;
spin_lock_irqsave(&rc_map->lock, flags);
@@ -524,7 +557,7 @@
if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
index = ke->index;
} else {
- retval = input_scancode_to_scalar(ke, &scancode);
+ retval = scancode_to_u64(ke, &scancode);
if (retval)
goto out;
@@ -538,7 +571,6 @@
ke->keycode = entry->keycode;
ke->len = sizeof(entry->scancode);
memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
-
} else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) {
/*
* We do not really know the valid range of scancodes
@@ -570,7 +602,7 @@
*
* return: the corresponding keycode, or KEY_RESERVED
*/
-u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
+u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode)
{
struct rc_map *rc_map = &dev->rc_map;
unsigned int keycode;
@@ -586,7 +618,7 @@
spin_unlock_irqrestore(&rc_map->lock, flags);
if (keycode != KEY_RESERVED)
- dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n",
+ dev_dbg(&dev->dev, "%s: scancode 0x%04llx keycode 0x%02x\n",
dev->device_name, scancode, keycode);
return keycode;
@@ -705,7 +737,7 @@
void rc_repeat(struct rc_dev *dev)
{
unsigned long flags;
- unsigned int timeout = nsecs_to_jiffies(dev->timeout) +
+ unsigned int timeout = usecs_to_jiffies(dev->timeout) +
msecs_to_jiffies(repeat_period(dev->last_protocol));
struct lirc_scancode sc = {
.scancode = dev->last_scancode, .rc_proto = dev->last_protocol,
@@ -715,12 +747,15 @@
};
if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
- ir_lirc_scancode_event(dev, &sc);
+ lirc_scancode_event(dev, &sc);
spin_lock_irqsave(&dev->keylock, flags);
- input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
- input_sync(dev->input_dev);
+ if (dev->last_scancode <= U32_MAX) {
+ input_event(dev->input_dev, EV_MSC, MSC_SCAN,
+ dev->last_scancode);
+ input_sync(dev->input_dev);
+ }
if (dev->keypressed) {
dev->keyup_jiffies = jiffies + timeout;
@@ -743,7 +778,7 @@
* called with keylock held.
*/
static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
- u32 scancode, u32 keycode, u8 toggle)
+ u64 scancode, u32 keycode, u8 toggle)
{
bool new_event = (!dev->keypressed ||
dev->last_protocol != protocol ||
@@ -756,12 +791,13 @@
};
if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
- ir_lirc_scancode_event(dev, &sc);
+ lirc_scancode_event(dev, &sc);
if (new_event && dev->keypressed)
ir_do_keyup(dev, false);
- input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
+ if (scancode <= U32_MAX)
+ input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
dev->last_protocol = protocol;
dev->last_scancode = scancode;
@@ -772,7 +808,7 @@
/* Register a keypress */
dev->keypressed = true;
- dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",
+ dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08llx\n",
dev->device_name, keycode, protocol, scancode);
input_report_key(dev->input_dev, keycode, 1);
@@ -809,7 +845,7 @@
* This routine is used to signal that a key has been pressed on the
* remote control.
*/
-void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
+void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
u8 toggle)
{
unsigned long flags;
@@ -819,7 +855,7 @@
ir_do_keydown(dev, protocol, scancode, keycode, toggle);
if (dev->keypressed) {
- dev->keyup_jiffies = jiffies + nsecs_to_jiffies(dev->timeout) +
+ dev->keyup_jiffies = jiffies + usecs_to_jiffies(dev->timeout) +
msecs_to_jiffies(repeat_period(protocol));
mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
}
@@ -840,7 +876,7 @@
* remote control. The driver must manually call rc_keyup() at a later stage.
*/
void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
- u32 scancode, u8 toggle)
+ u64 scancode, u8 toggle)
{
unsigned long flags;
u32 keycode = rc_g_keycode_from_table(dev, scancode);
@@ -1910,7 +1946,7 @@
* keycodes with rc_keydown, so lirc must be registered first.
*/
if (dev->allowed_protocols != RC_PROTO_BIT_CEC) {
- rc = ir_lirc_register(dev);
+ rc = lirc_register(dev);
if (rc < 0)
goto out_dev;
}
@@ -1936,7 +1972,7 @@
rc_free_rx_device(dev);
out_lirc:
if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
- ir_lirc_unregister(dev);
+ lirc_unregister(dev);
out_dev:
device_del(&dev->dev);
out_rx_free:
@@ -2000,7 +2036,7 @@
* that userspace polling will get notified.
*/
if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
- ir_lirc_unregister(dev);
+ lirc_unregister(dev);
device_del(&dev->dev);
@@ -2028,7 +2064,7 @@
if (rc) {
pr_err("rc_core: unable to init lirc\n");
class_unregister(&rc_class);
- return 0;
+ return rc;
}
led_trigger_register_simple("rc-feedback", &led_feedback);
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index aad9526..a61f982 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -340,7 +340,7 @@
{
struct ir_raw_event rawir = {};
struct device *dev;
- unsigned int i, sig_size, single_len, offset, val;
+ unsigned int i, sig_size, offset, val;
u32 mod_freq;
dev = rr3->dev;
@@ -361,7 +361,6 @@
for (i = 0; i < sig_size; i++) {
offset = rr3->irdata.sigdata[i];
val = get_unaligned_be16(&rr3->irdata.lens[offset]);
- single_len = redrat3_len_to_us(val);
/* we should always get pulse/space/pulse/space samples */
if (i % 2)
@@ -369,7 +368,7 @@
else
rawir.pulse = true;
- rawir.duration = US_TO_NS(single_len);
+ rawir.duration = redrat3_len_to_us(val);
/* cap the value to IR_MAX_DURATION */
rawir.duration = (rawir.duration > IR_MAX_DURATION) ?
IR_MAX_DURATION : rawir.duration;
@@ -405,7 +404,7 @@
udev = rr3->udev;
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), cmd,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0x0000, 0x0000, data, sizeof(u8), HZ * 10);
+ 0x0000, 0x0000, data, sizeof(u8), 10000);
if (res < 0) {
dev_err(rr3->dev, "%s: Error sending rr3 cmd res %d, data %d",
@@ -481,7 +480,7 @@
pipe = usb_rcvctrlpipe(rr3->udev, 0);
ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5);
+ RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, 5000);
if (ret != len)
dev_warn(rr3->dev, "Failed to read timeout from hardware\n");
else {
@@ -495,7 +494,7 @@
return timeout;
}
-static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutns)
+static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutus)
{
struct redrat3_dev *rr3 = rc_dev->priv;
struct usb_device *udev = rr3->udev;
@@ -507,11 +506,11 @@
if (!timeout)
return -ENOMEM;
- *timeout = cpu_to_be32(redrat3_us_to_len(timeoutns / 1000));
+ *timeout = cpu_to_be32(redrat3_us_to_len(timeoutus));
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
RR3_IR_IO_SIG_TIMEOUT, 0, timeout, sizeof(*timeout),
- HZ * 25);
+ 25000);
dev_dbg(dev, "set ir parm timeout %d ret 0x%02x\n",
be32_to_cpu(*timeout), ret);
@@ -543,32 +542,32 @@
*val = 0x01;
rc = usb_control_msg(udev, rxpipe, RR3_RESET,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- RR3_CPUCS_REG_ADDR, 0, val, len, HZ * 25);
+ RR3_CPUCS_REG_ADDR, 0, val, len, 25000);
dev_dbg(dev, "reset returned 0x%02x\n", rc);
*val = length_fuzz;
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- RR3_IR_IO_LENGTH_FUZZ, 0, val, len, HZ * 25);
+ RR3_IR_IO_LENGTH_FUZZ, 0, val, len, 25000);
dev_dbg(dev, "set ir parm len fuzz %d rc 0x%02x\n", *val, rc);
*val = (65536 - (minimum_pause * 2000)) / 256;
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- RR3_IR_IO_MIN_PAUSE, 0, val, len, HZ * 25);
+ RR3_IR_IO_MIN_PAUSE, 0, val, len, 25000);
dev_dbg(dev, "set ir parm min pause %d rc 0x%02x\n", *val, rc);
*val = periods_measure_carrier;
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- RR3_IR_IO_PERIODS_MF, 0, val, len, HZ * 25);
+ RR3_IR_IO_PERIODS_MF, 0, val, len, 25000);
dev_dbg(dev, "set ir parm periods measure carrier %d rc 0x%02x", *val,
rc);
*val = RR3_DRIVER_MAXLENS;
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- RR3_IR_IO_MAX_LENGTHS, 0, val, len, HZ * 25);
+ RR3_IR_IO_MAX_LENGTHS, 0, val, len, 25000);
dev_dbg(dev, "set ir parm max lens %d rc 0x%02x\n", *val, rc);
kfree(val);
@@ -586,7 +585,7 @@
rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0),
RR3_FW_VERSION,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, 0, buffer, RR3_FW_VERSION_LEN, HZ * 5);
+ 0, 0, buffer, RR3_FW_VERSION_LEN, 5000);
if (rc >= 0)
dev_info(rr3->dev, "Firmware rev: %s", buffer);
@@ -826,14 +825,14 @@
pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress);
ret = usb_bulk_msg(rr3->udev, pipe, irdata,
- sendbuf_len, &ret_len, 10 * HZ);
+ sendbuf_len, &ret_len, 10000);
dev_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, ret);
/* now tell the hardware to transmit what we sent it */
pipe = usb_rcvctrlpipe(rr3->udev, 0);
ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, 0, irdata, 2, HZ * 10);
+ 0, 0, irdata, 2, 10000);
if (ret < 0)
dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
@@ -947,15 +946,15 @@
rc->dev.parent = dev;
rc->priv = rr3;
rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
- rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
- rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
- rc->timeout = US_TO_NS(redrat3_get_timeout(rr3));
+ rc->min_timeout = MS_TO_US(RR3_RX_MIN_TIMEOUT);
+ rc->max_timeout = MS_TO_US(RR3_RX_MAX_TIMEOUT);
+ rc->timeout = redrat3_get_timeout(rr3);
rc->s_timeout = redrat3_set_timeout;
rc->tx_ir = redrat3_transmit_ir;
rc->s_tx_carrier = redrat3_set_tx_carrier;
rc->s_carrier_report = redrat3_wideband_receiver;
rc->driver_name = DRIVER_NAME;
- rc->rx_resolution = US_TO_NS(2);
+ rc->rx_resolution = 2;
rc->map_name = RC_MAP_HAUPPAUGE;
ret = rc_register_device(rc);
diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c
index 7652e98..96ae029 100644
--- a/drivers/media/rc/serial_ir.c
+++ b/drivers/media/rc/serial_ir.c
@@ -269,7 +269,7 @@
if (ptr > 0 && is_pulse) {
pulse += l;
- if (pulse > 250000) {
+ if (pulse > 250) {
ev.duration = space;
ev.pulse = false;
ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
@@ -283,13 +283,13 @@
}
if (!is_pulse) {
if (ptr == 0) {
- if (l > 20000000) {
+ if (l > 20000) {
space = l;
ptr++;
return;
}
} else {
- if (l > 20000000) {
+ if (l > 20000) {
space += pulse;
if (space > IR_MAX_DURATION)
space = IR_MAX_DURATION;
@@ -353,7 +353,7 @@
dcd = (status & hardware[type].signal_pin) ? 1 : 0;
if (dcd == last_dcd) {
- dev_err(&serial_ir.pdev->dev,
+ dev_dbg(&serial_ir.pdev->dev,
"ignoring spike: %d %d %lldns %lldns\n",
dcd, sense, ktime_to_ns(kt),
ktime_to_ns(serial_ir.lastkt));
@@ -376,7 +376,7 @@
sense = sense ? 0 : 1;
}
} else {
- data = ktime_to_ns(delkt);
+ data = ktime_to_us(delkt);
}
frbwrite(data, !(dcd ^ sense));
serial_ir.lastkt = kt;
@@ -385,7 +385,7 @@
} while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */
mod_timer(&serial_ir.timeout_timer,
- jiffies + nsecs_to_jiffies(serial_ir.rcdev->timeout));
+ jiffies + usecs_to_jiffies(serial_ir.rcdev->timeout));
ir_raw_event_handle(serial_ir.rcdev);
@@ -528,7 +528,7 @@
rcdev->min_timeout = 1;
rcdev->timeout = IR_DEFAULT_TIMEOUT;
rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
- rcdev->rx_resolution = 250000;
+ rcdev->rx_resolution = 250;
serial_ir.rcdev = rcdev;
@@ -547,7 +547,7 @@
/* Reserve io region. */
if ((iommap &&
- (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift,
+ (devm_request_mem_region(&dev->dev, iommap, 8UL << ioshift,
KBUILD_MODNAME) == NULL)) ||
(!iommap && (devm_request_region(&dev->dev, io, 8,
KBUILD_MODNAME) == NULL))) {
diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c
index 80b3a67..6ec96dc 100644
--- a/drivers/media/rc/sir_ir.c
+++ b/drivers/media/rc/sir_ir.c
@@ -110,7 +110,7 @@
} else {
val += TIME_CONST / 2;
}
- ev.duration = US_TO_NS(val);
+ ev.duration = val;
ir_raw_event_store_with_filter(rcdev, &ev);
}
diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c
index 1dc4e2e..3237fef 100644
--- a/drivers/media/rc/st_rc.c
+++ b/drivers/media/rc/st_rc.c
@@ -134,12 +134,12 @@
mark /= dev->sample_div;
}
- ev.duration = US_TO_NS(mark);
+ ev.duration = mark;
ev.pulse = true;
ir_raw_event_store(dev->rdev, &ev);
if (!last_symbol) {
- ev.duration = US_TO_NS(symbol);
+ ev.duration = symbol;
ev.pulse = false;
ir_raw_event_store(dev->rdev, &ev);
} else {
@@ -292,7 +292,7 @@
rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
/* rx sampling rate is 10Mhz */
rdev->rx_resolution = 100;
- rdev->timeout = US_TO_NS(MAX_SYMB_TIME);
+ rdev->timeout = MAX_SYMB_TIME;
rdev->priv = rc_dev;
rdev->open = st_rc_open;
rdev->close = st_rc_close;
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index 79a41fc..9f3cd9f 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -137,7 +137,6 @@
} else {
rawir.duration = delta;
rawir.duration -= sz->sum;
- rawir.duration = US_TO_NS(rawir.duration);
rawir.duration = (rawir.duration > IR_MAX_DURATION) ?
IR_MAX_DURATION : rawir.duration;
}
@@ -151,7 +150,6 @@
rawir.duration = ((int) value) * SZ_RESOLUTION;
rawir.duration += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
- rawir.duration = US_TO_NS(rawir.duration);
rawir.duration = (rawir.duration > IR_MAX_DURATION) ?
IR_MAX_DURATION : rawir.duration;
sz_push(sz, rawir);
@@ -172,7 +170,6 @@
rawir.duration = ((int) value) * SZ_RESOLUTION;
rawir.duration += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
- rawir.duration = US_TO_NS(rawir.duration);
sz_push(sz, rawir);
}
@@ -403,13 +400,12 @@
sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */
sz->timeout_enabled = true;
- sz->rdev->timeout = ((US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION) &
- IR_MAX_DURATION) | 0x03000000);
+ sz->rdev->timeout = SZ_TIMEOUT * SZ_RESOLUTION;
#if 0
/* not yet supported, depends on patches from maxim */
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
- sz->min_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION);
- sz->max_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION);
+ sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION;
+ sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION;
#endif
sz->signal_start = ktime_get_real();
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
index 78c5a4d..4afc589 100644
--- a/drivers/media/rc/sunxi-cir.c
+++ b/drivers/media/rc/sunxi-cir.c
@@ -243,8 +243,8 @@
ir->rc->dev.parent = dev;
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
/* Frequency after IR internal divider with sample period in ns */
- ir->rc->rx_resolution = (1000000000ul / (b_clk_freq / 64));
- ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT);
+ ir->rc->rx_resolution = (USEC_PER_SEC / (b_clk_freq / 64));
+ ir->rc->timeout = MS_TO_US(SUNXI_IR_TIMEOUT);
ir->rc->driver_name = SUNXI_IR_DEV;
ret = rc_register_device(ir->rc);
diff --git a/drivers/media/rc/tango-ir.c b/drivers/media/rc/tango-ir.c
index 451ec4e..b8eb5bc 100644
--- a/drivers/media/rc/tango-ir.c
+++ b/drivers/media/rc/tango-ir.c
@@ -157,20 +157,10 @@
struct device *dev = &pdev->dev;
struct rc_dev *rc;
struct tango_ir *ir;
- struct resource *rc5_res;
- struct resource *rc6_res;
u64 clkrate, clkdiv;
int irq, err;
u32 val;
- rc5_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!rc5_res)
- return -EINVAL;
-
- rc6_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!rc6_res)
- return -EINVAL;
-
irq = platform_get_irq(pdev, 0);
if (irq <= 0)
return -EINVAL;
@@ -179,11 +169,11 @@
if (!ir)
return -ENOMEM;
- ir->rc5_base = devm_ioremap_resource(dev, rc5_res);
+ ir->rc5_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ir->rc5_base))
return PTR_ERR(ir->rc5_base);
- ir->rc6_base = devm_ioremap_resource(dev, rc6_res);
+ ir->rc6_base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(ir->rc6_base))
return PTR_ERR(ir->rc6_base);
diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c
index 011a8b6..629787d 100644
--- a/drivers/media/rc/ttusbir.c
+++ b/drivers/media/rc/ttusbir.c
@@ -20,8 +20,8 @@
* messages per second (!), whether IR is idle or not.
*/
#define NUM_URBS 4
-#define NS_PER_BYTE 62500
-#define NS_PER_BIT (NS_PER_BYTE/8)
+#define US_PER_BYTE 62
+#define US_PER_BIT (US_PER_BYTE / 8)
struct ttusbir {
struct rc_dev *rc;
@@ -117,13 +117,13 @@
switch (v) {
case 0xfe:
rawir.pulse = false;
- rawir.duration = NS_PER_BYTE;
+ rawir.duration = US_PER_BYTE;
if (ir_raw_event_store_with_filter(tt->rc, &rawir))
event = true;
break;
case 0:
rawir.pulse = true;
- rawir.duration = NS_PER_BYTE;
+ rawir.duration = US_PER_BYTE;
if (ir_raw_event_store_with_filter(tt->rc, &rawir))
event = true;
break;
@@ -137,12 +137,12 @@
rawir.pulse = false;
}
- rawir.duration = NS_PER_BIT * (8 - b);
+ rawir.duration = US_PER_BIT * (8 - b);
if (ir_raw_event_store_with_filter(tt->rc, &rawir))
event = true;
rawir.pulse = !rawir.pulse;
- rawir.duration = NS_PER_BIT * b;
+ rawir.duration = US_PER_BIT * b;
if (ir_raw_event_store_with_filter(tt->rc, &rawir))
event = true;
break;
@@ -311,10 +311,10 @@
rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
/*
- * The precision is NS_PER_BIT, but since every 8th bit can be
- * overwritten with garbage the accuracy is at best 2 * NS_PER_BIT.
+ * The precision is US_PER_BIT, but since every 8th bit can be
+ * overwritten with garbage the accuracy is at best 2 * US_PER_BIT.
*/
- rc->rx_resolution = NS_PER_BIT;
+ rc->rx_resolution = 2 * US_PER_BIT;
ret = rc_register_device(rc);
if (ret) {
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 630e376..aed23ca 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -354,7 +354,6 @@
{
u8 irdata;
struct ir_raw_event rawir = {};
- unsigned duration;
/* Since RXHDLEV is set, at least 8 bytes are in the FIFO */
while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) {
@@ -362,13 +361,12 @@
if (data->rxstate == WBCIR_RXSTATE_ERROR)
continue;
- duration = ((irdata & 0x7F) + 1) *
+ rawir.duration = ((irdata & 0x7F) + 1) *
(data->carrier_report_enabled ? 2 : 10);
rawir.pulse = irdata & 0x80 ? false : true;
- rawir.duration = US_TO_NS(duration);
if (rawir.pulse)
- data->pulse_duration += duration;
+ data->pulse_duration += rawir.duration;
ir_raw_event_store_with_filter(data->dev, &rawir);
}
@@ -519,7 +517,7 @@
/* Set a higher sampling resolution if carrier reports are enabled */
wbcir_select_bank(data, WBCIR_BANK_2);
- data->dev->rx_resolution = US_TO_NS(enable ? 2 : 10);
+ data->dev->rx_resolution = enable ? 2 : 10;
outb(enable ? 0x03 : 0x0f, data->sbase + WBCIR_REG_SP3_BGDL);
outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
@@ -1076,7 +1074,7 @@
data->dev->min_timeout = 1;
data->dev->timeout = IR_DEFAULT_TIMEOUT;
data->dev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
- data->dev->rx_resolution = US_TO_NS(2);
+ data->dev->rx_resolution = 2;
data->dev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
data->dev->allowed_wakeup_protocols = RC_PROTO_BIT_NEC |
RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC5 |
diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c
index 4a3f2cc..98d0b43 100644
--- a/drivers/media/rc/xbox_remote.c
+++ b/drivers/media/rc/xbox_remote.c
@@ -157,7 +157,7 @@
rdev->device_name = xbox_remote->rc_name;
rdev->input_phys = xbox_remote->rc_phys;
- rdev->timeout = MS_TO_NS(10);
+ rdev->timeout = MS_TO_US(10);
usb_to_input_id(xbox_remote->udev, &rdev->input_id);
rdev->dev.parent = &xbox_remote->interface->dev;