diff options
Diffstat (limited to 'drivers/media/rc')
35 files changed, 350 insertions, 143 deletions
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 74d69ce22a33..0a8aeafdb7e0 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -184,6 +184,7 @@ config IR_GPIO_TX tristate "GPIO IR Bit Banging Transmitter" depends on LIRC depends on (OF && GPIOLIB) || COMPILE_TEST + depends on !PREEMPT_RT help Say Y if you want to a GPIO based IR transmitter. This is a bit banging driver. diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index d7721e60776e..a733914a2574 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -311,9 +311,9 @@ static void ati_remote_dump(struct device *dev, unsigned char *data, if (data[0] != (unsigned char)0xff && data[0] != 0x00) dev_warn(dev, "Weird byte 0x%02x\n", data[0]); } else if (len == 4) - dev_warn(dev, "Weird key %*ph\n", 4, data); + dev_warn(dev, "Weird key %4ph\n", data); else - dev_warn(dev, "Weird data, len=%d %*ph ...\n", len, 6, data); + dev_warn(dev, "Weird data, len=%d %6ph ...\n", len, data); } /* @@ -502,7 +502,7 @@ static void ati_remote_input_report(struct urb *urb) if (data[1] != ((data[2] + data[3] + 0xd5) & 0xff)) { dbginfo(&ati_remote->interface->dev, - "wrong checksum in input: %*ph\n", 4, data); + "wrong checksum in input: %4ph\n", data); return; } diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 11ee21a7db8f..d6c54a3bccc2 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -451,9 +451,6 @@ select_timeout: dev->rdev->max_timeout = 200000; } - if (dev->hw_learning_and_tx_capable) - dev->rdev->tx_resolution = sample_period; - if (dev->rdev->timeout > dev->rdev->max_timeout) dev->rdev->timeout = dev->rdev->max_timeout; if (dev->rdev->timeout < dev->rdev->min_timeout) @@ -662,7 +659,7 @@ exit: /* timer to simulate tx done interrupt */ static void ene_tx_irqsim(struct timer_list *t) { - struct ene_device *dev = from_timer(dev, t, tx_sim_timer); + struct ene_device *dev = timer_container_of(dev, t, tx_sim_timer); unsigned long flags; spin_lock_irqsave(&dev->hw_lock, flags); @@ -1107,7 +1104,7 @@ static void ene_remove(struct pnp_dev *pnp_dev) unsigned long flags; rc_unregister_device(dev->rdev); - del_timer_sync(&dev->tx_sim_timer); + timer_delete_sync(&dev->tx_sim_timer); spin_lock_irqsave(&dev->hw_lock, flags); ene_rx_disable(dev); ene_rx_restore_hw_buffer(dev); diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 41eeec648803..bf6d8fa983bf 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -9,7 +9,6 @@ #include <linux/gpio/consumer.h> #include <linux/slab.h> #include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/pm_qos.h> @@ -202,7 +201,7 @@ MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match); static struct platform_driver gpio_ir_recv_driver = { .probe = gpio_ir_recv_probe, - .remove_new = gpio_ir_recv_remove, + .remove = gpio_ir_recv_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = gpio_ir_recv_of_match, diff --git a/drivers/media/rc/gpio-ir-tx.c b/drivers/media/rc/gpio-ir-tx.c index 1a8fea357f14..e185ead40464 100644 --- a/drivers/media/rc/gpio-ir-tx.c +++ b/drivers/media/rc/gpio-ir-tx.c @@ -78,8 +78,6 @@ static void gpio_ir_tx_unmodulated(struct gpio_ir *gpio_ir, uint *txbuf, ktime_t edge; int i; - local_irq_disable(); - edge = ktime_get(); for (i = 0; i < count; i++) { @@ -110,8 +108,6 @@ static void gpio_ir_tx_modulated(struct gpio_ir *gpio_ir, uint *txbuf, space = DIV_ROUND_CLOSEST((100 - gpio_ir->duty_cycle) * (NSEC_PER_SEC / 100), gpio_ir->carrier); - local_irq_disable(); - edge = ktime_get(); for (i = 0; i < count; i++) { diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index 1464ef9c55bc..e034c93d57cf 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -131,7 +131,7 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd) static void igorplugusb_timer(struct timer_list *t) { - struct igorplugusb *ir = from_timer(ir, t, timer); + struct igorplugusb *ir = timer_container_of(ir, t, timer); igorplugusb_cmd(ir, GET_INFRACODE); } @@ -223,7 +223,7 @@ static int igorplugusb_probe(struct usb_interface *intf, return 0; fail: usb_poison_urb(ir->urb); - del_timer(&ir->timer); + timer_delete(&ir->timer); usb_unpoison_urb(ir->urb); usb_free_urb(ir->urb); rc_free_device(ir->rc); @@ -238,7 +238,7 @@ static void igorplugusb_disconnect(struct usb_interface *intf) rc_unregister_device(ir->rc); usb_poison_urb(ir->urb); - del_timer_sync(&ir->timer); + timer_delete_sync(&ir->timer); usb_set_intfdata(intf, NULL); usb_unpoison_urb(ir->urb); usb_free_urb(ir->urb); diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 276bf3c8a8cb..8af94246e591 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -194,8 +194,10 @@ static int iguanair_send(struct iguanair *ir, unsigned size) if (rc) return rc; - if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) + if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) { + usb_kill_urb(ir->urb_out); return -ETIMEDOUT; + } return rc; } diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c index d87d8e14c556..067f4bc7fcc3 100644 --- a/drivers/media/rc/img-ir/img-ir-core.c +++ b/drivers/media/rc/img-ir/img-ir-core.c @@ -181,7 +181,7 @@ static struct platform_driver img_ir_driver = { .pm = &img_ir_pmops, }, .probe = img_ir_probe, - .remove_new = img_ir_remove, + .remove = img_ir_remove, }; module_platform_driver(img_ir_driver); diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index 5da7479c1793..63f6f5b36838 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -556,8 +556,8 @@ static void img_ir_set_decoder(struct img_ir_priv *priv, * acquires the lock and we don't want to deadlock waiting for it. */ spin_unlock_irq(&priv->lock); - del_timer_sync(&hw->end_timer); - del_timer_sync(&hw->suspend_timer); + timer_delete_sync(&hw->end_timer); + timer_delete_sync(&hw->suspend_timer); spin_lock_irq(&priv->lock); hw->stopping = false; @@ -865,7 +865,7 @@ static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw) /* timer function to end waiting for repeat. */ static void img_ir_end_timer(struct timer_list *t) { - struct img_ir_priv *priv = from_timer(priv, t, hw.end_timer); + struct img_ir_priv *priv = timer_container_of(priv, t, hw.end_timer); spin_lock_irq(&priv->lock); img_ir_end_repeat(priv); @@ -879,7 +879,8 @@ static void img_ir_end_timer(struct timer_list *t) */ static void img_ir_suspend_timer(struct timer_list *t) { - struct img_ir_priv *priv = from_timer(priv, t, hw.suspend_timer); + struct img_ir_priv *priv = timer_container_of(priv, t, + hw.suspend_timer); spin_lock_irq(&priv->lock); /* diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c index 8b0bdd9603b3..92fb7b555a0f 100644 --- a/drivers/media/rc/img-ir/img-ir-raw.c +++ b/drivers/media/rc/img-ir/img-ir-raw.c @@ -65,7 +65,7 @@ void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status) */ static void img_ir_echo_timer(struct timer_list *t) { - struct img_ir_priv *priv = from_timer(priv, t, raw.timer); + struct img_ir_priv *priv = timer_container_of(priv, t, raw.timer); spin_lock_irq(&priv->lock); @@ -147,5 +147,5 @@ void img_ir_remove_raw(struct img_ir_priv *priv) rc_unregister_device(rdev); - del_timer_sync(&raw->timer); + timer_delete_sync(&raw->timer); } diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 5719dda6e0f0..f5221b018808 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -845,13 +845,13 @@ static ssize_t imon_clock_show(struct device *d, mutex_lock(&ictx->lock); if (!ictx->display_supported) { - len = snprintf(buf, PAGE_SIZE, "Not supported."); + len = sysfs_emit(buf, "Not supported."); } else { - len = snprintf(buf, PAGE_SIZE, - "To set the clock on your iMON display:\n" - "# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n" - "%s", ictx->display_isopen ? - "\nNOTE: imon device must be closed\n" : ""); + len = sysfs_emit(buf, + "To set the clock on your iMON display:\n" + "# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n" + "%s", ictx->display_isopen ? + "\nNOTE: imon device must be closed\n" : ""); } mutex_unlock(&ictx->lock); @@ -1091,7 +1091,7 @@ static void usb_tx_callback(struct urb *urb) */ static void imon_touch_display_timeout(struct timer_list *t) { - struct imon_context *ictx = from_timer(ictx, t, ttimer); + struct imon_context *ictx = timer_container_of(ictx, t, ttimer); if (ictx->display_type != IMON_DISPLAY_TYPE_VGA) return; @@ -1148,10 +1148,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); - if (!mutex_is_locked(&ictx->lock)) { - unlock = true; - mutex_lock(&ictx->lock); - } + unlock = mutex_trylock(&ictx->lock); retval = send_packet(ictx); if (retval) @@ -2537,7 +2534,7 @@ static void imon_disconnect(struct usb_interface *interface) ictx->dev_present_intf1 = false; usb_kill_urb(ictx->rx_urb_intf1); if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { - del_timer_sync(&ictx->ttimer); + timer_delete_sync(&ictx->ttimer); input_unregister_device(ictx->touch); } usb_put_dev(ictx->usbdev_intf1); diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c index b02ded52f19e..3a526dea6532 100644 --- a/drivers/media/rc/imon_raw.c +++ b/drivers/media/rc/imon_raw.c @@ -37,7 +37,7 @@ static void imon_ir_data(struct imon *imon) if (packet_no == 0xff) return; - dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf); + dev_dbg(imon->dev, "data: %8ph", imon->ir_buf); /* * Only the first 5 bytes contain IR data. Right shift so we move diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index de5bb9a08ea4..afd80d2350c6 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -394,7 +394,7 @@ static struct platform_driver hix5hd2_ir_driver = { .pm = &hix5hd2_ir_pm_ops, }, .probe = hix5hd2_ir_probe, - .remove_new = hix5hd2_ir_remove, + .remove = hix5hd2_ir_remove, }; module_platform_driver(hix5hd2_ir_driver); diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 66e8feb9a569..bb2d7c37c263 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -109,7 +109,8 @@ static unsigned char kbd_keycodes[256] = { static void mce_kbd_rx_timeout(struct timer_list *t) { - struct ir_raw_event_ctrl *raw = from_timer(raw, t, mce_kbd.rx_timeout); + struct ir_raw_event_ctrl *raw = timer_container_of(raw, t, + mce_kbd.rx_timeout); unsigned char maskcode; unsigned long flags; int i; @@ -324,7 +325,7 @@ again: msecs_to_jiffies(100); mod_timer(&data->rx_timeout, jiffies + delay); } else { - del_timer(&data->rx_timeout); + timer_delete(&data->rx_timeout); } /* Pass data to keyboard buffer parser */ ir_mce_kbd_process_keyboard_data(dev, scancode); @@ -372,7 +373,7 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev) { struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd; - del_timer_sync(&mce_kbd->rx_timeout); + timer_delete_sync(&mce_kbd->rx_timeout); return 0; } diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index bbc81bed4f90..8fc8e496e6aa 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -4,13 +4,18 @@ // Copyright (c) 2016 Samsung Electronics Co., Ltd. // Copyright (c) Andi Shyti <andi@etezian.org> -#include <linux/delay.h> -#include <linux/fs.h> +#include <linux/bits.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/math.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/mutex.h> -#include <linux/of_gpio.h> +#include <linux/property.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> +#include <linux/string.h> +#include <linux/types.h> + #include <media/rc-core.h> #define IR_SPI_DRIVER_NAME "ir-spi" @@ -31,8 +36,7 @@ struct ir_spi_data { struct regulator *regulator; }; -static int ir_spi_tx(struct rc_dev *dev, - unsigned int *buffer, unsigned int count) +static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int count) { int i; int ret; @@ -52,7 +56,7 @@ static int ir_spi_tx(struct rc_dev *dev, return -EINVAL; /* - * the first value in buffer is a pulse, so that 0, 2, 4, ... + * The first value in buffer is a pulse, so that 0, 2, 4, ... * contain a pulse duration. On the contrary, 1, 3, 5, ... * contain a space duration. */ @@ -111,15 +115,16 @@ static int ir_spi_set_duty_cycle(struct rc_dev *dev, u32 duty_cycle) static int ir_spi_probe(struct spi_device *spi) { + struct device *dev = &spi->dev; int ret; u8 dc; struct ir_spi_data *idata; - idata = devm_kzalloc(&spi->dev, sizeof(*idata), GFP_KERNEL); + idata = devm_kzalloc(dev, sizeof(*idata), GFP_KERNEL); if (!idata) return -ENOMEM; - idata->regulator = devm_regulator_get(&spi->dev, "irda_regulator"); + idata->regulator = devm_regulator_get(dev, "irda_regulator"); if (IS_ERR(idata->regulator)) return PTR_ERR(idata->regulator); @@ -135,32 +140,31 @@ static int ir_spi_probe(struct spi_device *spi) idata->rc->priv = idata; idata->spi = spi; - idata->negated = of_property_read_bool(spi->dev.of_node, - "led-active-low"); - ret = of_property_read_u8(spi->dev.of_node, "duty-cycle", &dc); + idata->negated = device_property_read_bool(dev, "led-active-low"); + ret = device_property_read_u8(dev, "duty-cycle", &dc); if (ret) dc = 50; - /* ir_spi_set_duty_cycle cannot fail, - * it returns int to be compatible with the - * rc->s_tx_duty_cycle function + /* + * ir_spi_set_duty_cycle() cannot fail, it returns int + * to be compatible with the rc->s_tx_duty_cycle function. */ ir_spi_set_duty_cycle(idata->rc, dc); idata->freq = IR_SPI_DEFAULT_FREQUENCY; - return devm_rc_register_device(&spi->dev, idata->rc); + return devm_rc_register_device(dev, idata->rc); } static const struct of_device_id ir_spi_of_match[] = { { .compatible = "ir-spi-led" }, - {}, + {} }; MODULE_DEVICE_TABLE(of, ir_spi_of_match); static const struct spi_device_id ir_spi_ids[] = { { "ir-spi-led" }, - {}, + {} }; MODULE_DEVICE_TABLE(spi, ir_spi_ids); @@ -172,7 +176,6 @@ static struct spi_driver ir_spi_driver = { .of_match_table = ir_spi_of_match, }, }; - module_spi_driver(ir_spi_driver); MODULE_AUTHOR("Andi Shyti <andi@etezian.org>"); diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c index 69e630d85262..533faa117517 100644 --- a/drivers/media/rc/ir_toy.c +++ b/drivers/media/rc/ir_toy.c @@ -12,7 +12,7 @@ * Copyright (C) 2011 Peter Kooiman <pkooiman@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/completion.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index fcfadd7ea31c..2bacecb02262 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1380,7 +1380,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev->timeout = IR_DEFAULT_TIMEOUT; rdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; rdev->rx_resolution = ITE_BAUDRATE_DIVISOR * sample_period / 1000; - rdev->tx_resolution = ITE_BAUDRATE_DIVISOR * sample_period / 1000; /* set up transmitter related values */ rdev->tx_ir = ite_tx_ir; diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index f19558fdab0c..d04572627cdd 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_RC_MAP) += \ rc-msi-digivox-ii.o \ rc-msi-tvanywhere.o \ rc-msi-tvanywhere-plus.o \ + rc-mygica-utv3.o \ rc-nebula.o \ rc-nec-terratec-cinergy-xs.o \ rc-norwood.o \ @@ -105,6 +106,7 @@ obj-$(CONFIG_RC_MAP) += \ rc-rc6-mce.o \ rc-real-audio-220-32-keys.o \ rc-reddo.o \ + rc-siemens-gigaset-rc20.o \ rc-snapstream-firefly.o \ rc-streamzap.o \ rc-su3000.o \ diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c index d7156774aa0e..9e64c0b2d18e 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge.c +++ b/drivers/media/rc/keymaps/rc-hauppauge.c @@ -261,6 +261,48 @@ static struct rc_map_table rc5_hauppauge_new[] = { { 0x001e, KEY_RED }, /* Reserved */ { 0x0000, KEY_NUMERIC_0 }, { 0x0026, KEY_SLEEP }, /* Minimize */ + + /* + * Keycodes for the black Credit Card Remote Control shipped with, for + * example, the WinTV-dualHD tuner. + * Keycodes start with address = 0x19 + */ + { 0x190a, KEY_LAST }, /* <- */ + { 0x192f, KEY_MENU }, /* List */ + { 0x1910, KEY_CHANNELUP }, + { 0x192e, KEY_CHANNELDOWN }, + { 0x192c, KEY_OK }, + + { 0x1911, KEY_TV }, + { 0x190c, KEY_POWER }, + + { 0x1900, KEY_NUMERIC_0 }, + { 0x1938, KEY_NUMERIC_1 }, + { 0x1920, KEY_NUMERIC_2 }, + { 0x1901, KEY_NUMERIC_3 }, + { 0x1902, KEY_NUMERIC_4 }, + { 0x1904, KEY_NUMERIC_5 }, + { 0x1905, KEY_NUMERIC_6 }, + { 0x1907, KEY_NUMERIC_7 }, + { 0x1908, KEY_NUMERIC_8 }, + { 0x190f, KEY_NUMERIC_9 }, + + { 0x1921, KEY_VOLUMEUP }, + { 0x1903, KEY_VOLUMEDOWN }, + { 0x1906, KEY_MUTE }, + + { 0x1909, KEY_CAMERA }, /* Snap */ + { 0x1922, KEY_SUBTITLE }, /* CC */ + { 0x192b, KEY_INFO }, + + { 0x1929, KEY_END }, /* Skip to live TV */ + { 0x190d, KEY_PLAYPAUSE }, + { 0x1926, KEY_STOP }, + { 0x192a, KEY_RECORD }, + { 0x193a, KEY_PREVIOUS }, /* |< */ + { 0x193b, KEY_REWIND }, /* << */ + { 0x193c, KEY_FASTFORWARD }, /* >> */ + { 0x193d, KEY_NEXT }, /* >| */ }; static struct rc_map_list rc5_hauppauge_new_map = { diff --git a/drivers/media/rc/keymaps/rc-mygica-utv3.c b/drivers/media/rc/keymaps/rc-mygica-utv3.c new file mode 100644 index 000000000000..f32b8281459b --- /dev/null +++ b/drivers/media/rc/keymaps/rc-mygica-utv3.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* rc-mygica-utv3.c - Keytable for the MyGica UTV3 Analog USB2.0 TV Box + * + * Copyright (c) 2024 by Nils Rothaug + */ + +#include <media/rc-map.h> +#include <linux/module.h> + +static struct rc_map_table mygica_utv3[] = { + { 0x0d, KEY_MUTE }, + { 0x38, KEY_VIDEO }, /* Source */ + { 0x14, KEY_RADIO }, /* FM Radio */ + { 0x0c, KEY_POWER2 }, + + { 0x01, KEY_NUMERIC_1}, + { 0x02, KEY_NUMERIC_2}, + { 0x03, KEY_NUMERIC_3}, + { 0x04, KEY_NUMERIC_4}, + { 0x05, KEY_NUMERIC_5}, + { 0x06, KEY_NUMERIC_6}, + { 0x07, KEY_NUMERIC_7}, + { 0x08, KEY_NUMERIC_8}, + { 0x09, KEY_NUMERIC_9}, + { 0x00, KEY_NUMERIC_0}, + + { 0x0a, KEY_DIGITS }, /* Single/double/triple digit */ + { 0x0e, KEY_CAMERA }, /* Snapshot */ + { 0x0f, KEY_ZOOM }, /* Full Screen */ + { 0x29, KEY_LAST }, /* Recall (return to previous channel) */ + + { 0x17, KEY_PLAY }, + { 0x1f, KEY_RECORD }, + { 0x0b, KEY_STOP }, + { 0x16, KEY_PAUSE }, + + { 0x20, KEY_CHANNELUP }, + { 0x21, KEY_CHANNELDOWN }, + { 0x10, KEY_VOLUMEUP }, + { 0x11, KEY_VOLUMEDOWN }, + { 0x26, KEY_REWIND }, + { 0x27, KEY_FASTFORWARD }, +}; + +static struct rc_map_list mygica_utv3_map = { + .map = { + .scan = mygica_utv3, + .size = ARRAY_SIZE(mygica_utv3), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_MYGICA_UTV3, + } +}; + +static int __init init_rc_map_mygica_utv3(void) +{ + return rc_map_register(&mygica_utv3_map); +} + +static void __exit exit_rc_map_mygica_utv3(void) +{ + rc_map_unregister(&mygica_utv3_map); +} + +module_init(init_rc_map_mygica_utv3) +module_exit(exit_rc_map_mygica_utv3) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nils Rothaug"); +MODULE_DESCRIPTION("MyGica UTV3 Analog USB2.0 TV Box remote keytable"); diff --git a/drivers/media/rc/keymaps/rc-siemens-gigaset-rc20.c b/drivers/media/rc/keymaps/rc-siemens-gigaset-rc20.c new file mode 100644 index 000000000000..defc77932e10 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-siemens-gigaset-rc20.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* rc-siemens-gigaset-rc20.c - Keytable for the Siemens Gigaset RC 20 remote + * + * Copyright (c) 2025 by Michael Klein + */ + +#include <media/rc-map.h> +#include <linux/module.h> + +static struct rc_map_table siemens_gigaset_rc20[] = { + { 0x1501, KEY_POWER }, + { 0x1502, KEY_MUTE }, + { 0x1503, KEY_NUMERIC_1 }, + { 0x1504, KEY_NUMERIC_2 }, + { 0x1505, KEY_NUMERIC_3 }, + { 0x1506, KEY_NUMERIC_4 }, + { 0x1507, KEY_NUMERIC_5 }, + { 0x1508, KEY_NUMERIC_6 }, + { 0x1509, KEY_NUMERIC_7 }, + { 0x150a, KEY_NUMERIC_8 }, + { 0x150b, KEY_NUMERIC_9 }, + { 0x150c, KEY_NUMERIC_0 }, + { 0x150d, KEY_UP }, + { 0x150e, KEY_LEFT }, + { 0x150f, KEY_OK }, + { 0x1510, KEY_RIGHT }, + { 0x1511, KEY_DOWN }, + { 0x1512, KEY_SHUFFLE }, /* double-arrow */ + { 0x1513, KEY_EXIT }, + { 0x1514, KEY_RED }, + { 0x1515, KEY_GREEN }, + { 0x1516, KEY_YELLOW }, /* OPT */ + { 0x1517, KEY_BLUE }, + { 0x1518, KEY_MENU }, + { 0x1519, KEY_TEXT }, + { 0x151a, KEY_MODE }, /* TV/Radio */ + + { 0x1521, KEY_EPG }, + { 0x1522, KEY_FAVORITES }, + { 0x1523, KEY_CHANNELUP }, + { 0x1524, KEY_CHANNELDOWN }, + { 0x1525, KEY_VOLUMEUP }, + { 0x1526, KEY_VOLUMEDOWN }, + { 0x1527, KEY_INFO }, +}; + +static struct rc_map_list siemens_gigaset_rc20_map = { + .map = { + .scan = siemens_gigaset_rc20, + .size = ARRAY_SIZE(siemens_gigaset_rc20), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_SIEMENS_GIGASET_RC20, + } +}; + +static int __init init_rc_map_siemens_gigaset_rc20(void) +{ + return rc_map_register(&siemens_gigaset_rc20_map); +} + +static void __exit exit_rc_map_siemens_gigaset_rc20(void) +{ + rc_map_unregister(&siemens_gigaset_rc20_map); +} + +module_init(init_rc_map_siemens_gigaset_rc20) +module_exit(exit_rc_map_siemens_gigaset_rc20) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michael Klein"); +MODULE_DESCRIPTION("Siemens Gigaset RC20 remote keytable"); diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index caad59f76793..a2257dc2f25d 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -27,7 +27,9 @@ static dev_t lirc_base_dev; static DEFINE_IDA(lirc_ida); /* Only used for sysfs but defined to void otherwise */ -static struct class *lirc_class; +static const struct class lirc_class = { + .name = "lirc", +}; /** * lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace @@ -704,7 +706,6 @@ static const struct file_operations lirc_fops = { .poll = lirc_poll, .open = lirc_open, .release = lirc_close, - .llseek = no_llseek, }; static void lirc_release_device(struct device *ld) @@ -724,7 +725,7 @@ int lirc_register(struct rc_dev *dev) return minor; device_initialize(&dev->lirc_dev); - dev->lirc_dev.class = lirc_class; + dev->lirc_dev.class = &lirc_class; dev->lirc_dev.parent = &dev->dev; dev->lirc_dev.release = lirc_release_device; dev->lirc_dev.devt = MKDEV(MAJOR(lirc_base_dev), minor); @@ -789,15 +790,13 @@ int __init lirc_dev_init(void) { int retval; - lirc_class = class_create("lirc"); - if (IS_ERR(lirc_class)) { - pr_err("class_create failed\n"); - return PTR_ERR(lirc_class); - } + retval = class_register(&lirc_class); + if (retval) + return retval; retval = alloc_chrdev_region(&lirc_base_dev, 0, RC_DEV_MAX, "lirc"); if (retval) { - class_destroy(lirc_class); + class_unregister(&lirc_class); pr_err("alloc_chrdev_region failed\n"); return retval; } @@ -810,32 +809,29 @@ int __init lirc_dev_init(void) void __exit lirc_dev_exit(void) { - class_destroy(lirc_class); + class_unregister(&lirc_class); unregister_chrdev_region(lirc_base_dev, RC_DEV_MAX); } struct rc_dev *rc_dev_get_from_fd(int fd, bool write) { - struct fd f = fdget(fd); + CLASS(fd, f)(fd); struct lirc_fh *fh; struct rc_dev *dev; - if (!f.file) + if (fd_empty(f)) return ERR_PTR(-EBADF); - if (f.file->f_op != &lirc_fops) { - fdput(f); + if (fd_file(f)->f_op != &lirc_fops) return ERR_PTR(-EINVAL); - } - if (write && !(f.file->f_mode & FMODE_WRITE)) + if (write && !(fd_file(f)->f_mode & FMODE_WRITE)) return ERR_PTR(-EPERM); - fh = f.file->private_data; + fh = fd_file(f)->private_data; dev = fh->rc; get_device(&dev->dev); - fdput(f); return dev; } diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index c76ba24c1f55..044767eb3a38 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -28,7 +28,6 @@ #include <linux/workqueue.h> #include <linux/usb.h> #include <linux/usb/input.h> -#include <linux/pm_wakeup.h> #include <media/rc-core.h> #define DRIVER_VERSION "1.95" @@ -494,7 +493,6 @@ struct mceusb_dev { u32 carrier; unsigned char tx_mask; - char name[128]; char phys[64]; enum mceusb_model_type model; @@ -659,8 +657,8 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, u8 *buf, int buf_len, if (len == 2) dev_dbg(dev, "Get hw/sw rev?"); else - dev_dbg(dev, "hw/sw rev %*ph", - 4, &buf[offset + 2]); + dev_dbg(dev, "hw/sw rev %4ph", + &buf[offset + 2]); break; case MCE_CMD_RESUME: dev_dbg(dev, "Device resume requested"); @@ -774,7 +772,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, u8 *buf, int buf_len, /* * Schedule work that can't be done in interrupt handlers - * (mceusb_dev_recv() and mce_write_callback()) nor tasklets. + * (mceusb_dev_recv() and mce_write_callback()) nor BH work. * Invokes mceusb_deferred_kevent() for recovering from * error events specified by the kevent bit field. */ @@ -1591,16 +1589,10 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) goto out; } - snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)", - mceusb_model[ir->model].name ? - mceusb_model[ir->model].name : - "Media Center Ed. eHome Infrared Remote Transceiver", - le16_to_cpu(ir->usbdev->descriptor.idVendor), - le16_to_cpu(ir->usbdev->descriptor.idProduct)); - usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys)); - rc->device_name = ir->name; + rc->device_name = mceusb_model[ir->model].name ? : + "Media Center Ed. eHome Infrared Remote Transceiver"; rc->input_phys = ir->phys; usb_to_input_id(ir->usbdev, &rc->input_id); rc->dev.parent = dev; diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index 5303e6da5809..272ebb0d97c8 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -567,6 +567,32 @@ static void meson_ir_shutdown(struct platform_device *pdev) spin_unlock_irqrestore(&ir->lock, flags); } +static __maybe_unused int meson_ir_resume(struct device *dev) +{ + struct meson_ir *ir = dev_get_drvdata(dev); + + if (ir->param->support_hw_decoder) + meson_ir_hw_decoder_init(ir->rc, &ir->rc->enabled_protocols); + else + meson_ir_sw_decoder_init(ir->rc); + + return 0; +} + +static __maybe_unused int meson_ir_suspend(struct device *dev) +{ + struct meson_ir *ir = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&ir->lock, flags); + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_ENABLE, 0); + spin_unlock_irqrestore(&ir->lock, flags); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(meson_ir_pm_ops, meson_ir_suspend, meson_ir_resume); + static const struct meson_ir_param meson6_ir_param = { .support_hw_decoder = false, .max_register = IR_DEC_REG1, @@ -602,11 +628,12 @@ MODULE_DEVICE_TABLE(of, meson_ir_match); static struct platform_driver meson_ir_driver = { .probe = meson_ir_probe, - .remove_new = meson_ir_remove, + .remove = meson_ir_remove, .shutdown = meson_ir_shutdown, .driver = { .name = DRIVER_NAME, .of_match_table = meson_ir_match, + .pm = pm_ptr(&meson_ir_pm_ops), }, }; diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c index 4e294e59d3cb..85c9436b0a20 100644 --- a/drivers/media/rc/mtk-cir.c +++ b/drivers/media/rc/mtk-cir.c @@ -8,6 +8,7 @@ #include <linux/clk.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/io.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/reset.h> @@ -439,7 +440,7 @@ static void mtk_ir_remove(struct platform_device *pdev) static struct platform_driver mtk_ir_driver = { .probe = mtk_ir_probe, - .remove_new = mtk_ir_remove, + .remove = mtk_ir_remove, .driver = { .name = MTK_IR_DEV, .of_match_table = mtk_ir_match, diff --git a/drivers/media/rc/pwm-ir-tx.c b/drivers/media/rc/pwm-ir-tx.c index fe368aebbc13..84533fdd61aa 100644 --- a/drivers/media/rc/pwm-ir-tx.c +++ b/drivers/media/rc/pwm-ir-tx.c @@ -172,8 +172,7 @@ static int pwm_ir_probe(struct platform_device *pdev) rcdev->tx_ir = pwm_ir_tx_sleep; } else { init_completion(&pwm_ir->tx_done); - hrtimer_init(&pwm_ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - pwm_ir->timer.function = pwm_ir_timer; + hrtimer_setup(&pwm_ir->timer, pwm_ir_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); rcdev->tx_ir = pwm_ir_tx_atomic; } diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 7df949fc65e2..4967d87ec4b7 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -85,8 +85,8 @@ struct ir_raw_event_ctrl { struct rc6_dec { int state; u8 header; - u32 body; bool toggle; + u32 body; unsigned count; unsigned wanted_bits; } rc6; @@ -127,8 +127,8 @@ struct ir_raw_event_ctrl { struct mce_kbd_dec { /* locks key up timer */ spinlock_t keylock; - struct timer_list rx_timeout; int state; + struct timer_list rx_timeout; u8 header; u32 body; unsigned count; diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 16e33d7eaaa2..5dafe11f61c6 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -552,7 +552,8 @@ EXPORT_SYMBOL(ir_raw_encode_scancode); */ static void ir_raw_edge_handle(struct timer_list *t) { - struct ir_raw_event_ctrl *raw = from_timer(raw, t, edge_handle); + struct ir_raw_event_ctrl *raw = timer_container_of(raw, t, + edge_handle); struct rc_dev *dev = raw->dev; unsigned long flags; ktime_t interval; @@ -662,7 +663,7 @@ void ir_raw_event_unregister(struct rc_dev *dev) return; kthread_stop(dev->raw->thread); - del_timer_sync(&dev->raw->edge_handle); + timer_delete_sync(&dev->raw->edge_handle); mutex_lock(&ir_raw_handler_lock); list_del(&dev->raw->list); diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index b356041c5c00..8288366f891f 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -230,7 +230,6 @@ static int __init loop_init(void) rc->min_timeout = 1; rc->max_timeout = IR_MAX_TIMEOUT; 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 6bdad6341844..b9bf5cdcde4a 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -639,7 +639,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync) return; dev_dbg(&dev->dev, "keyup key 0x%04x\n", dev->last_keycode); - del_timer(&dev->timer_repeat); + timer_delete(&dev->timer_repeat); input_report_key(dev->input_dev, dev->last_keycode, 0); led_trigger_event(led_feedback, LED_OFF); if (sync) @@ -674,7 +674,7 @@ EXPORT_SYMBOL_GPL(rc_keyup); */ static void ir_timer_keyup(struct timer_list *t) { - struct rc_dev *dev = from_timer(dev, t, timer_keyup); + struct rc_dev *dev = timer_container_of(dev, t, timer_keyup); unsigned long flags; /* @@ -703,7 +703,7 @@ static void ir_timer_keyup(struct timer_list *t) */ static void ir_timer_repeat(struct timer_list *t) { - struct rc_dev *dev = from_timer(dev, t, timer_repeat); + struct rc_dev *dev = timer_container_of(dev, t, timer_repeat); struct input_dev *input = dev->input_dev; unsigned long flags; @@ -2021,8 +2021,8 @@ void rc_unregister_device(struct rc_dev *dev) if (dev->driver_type == RC_DRIVER_IR_RAW) ir_raw_event_unregister(dev); - del_timer_sync(&dev->timer_keyup); - del_timer_sync(&dev->timer_repeat); + timer_delete_sync(&dev->timer_keyup); + timer_delete_sync(&dev->timer_repeat); mutex_lock(&dev->lock); if (dev->users && dev->close) @@ -2092,4 +2092,5 @@ subsys_initcall(rc_core_init); module_exit(rc_core_exit); MODULE_AUTHOR("Mauro Carvalho Chehab"); +MODULE_DESCRIPTION("Remote Controller core module"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 9f2947af33aa..d89a4cfe3c89 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -31,7 +31,7 @@ * -- */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/device.h> #include <linux/leds.h> #include <linux/module.h> diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 96ae0294ac10..992fff82b524 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/errno.h> #include <linux/interrupt.h> +#include <linux/io.h> #include <linux/kernel.h> #include <linux/serial_reg.h> #include <linux/types.h> @@ -797,7 +798,7 @@ static int __init serial_ir_init_module(void) static void __exit serial_ir_exit_module(void) { - del_timer_sync(&serial_ir.timeout_timer); + timer_delete_sync(&serial_ir.timeout_timer); serial_ir_exit(); } diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 28477aa95563..6539fa0a6e79 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -6,6 +6,7 @@ #include <linux/kernel.h> #include <linux/clk.h> #include <linux/interrupt.h> +#include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -407,7 +408,7 @@ static struct platform_driver st_rc_driver = { .pm = &st_rc_pm_ops, }, .probe = st_rc_probe, - .remove_new = st_rc_remove, + .remove = st_rc_remove, }; module_platform_driver(st_rc_driver); diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 9b209e687f25..d3b48a0dd1f4 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -138,39 +138,10 @@ static void sz_push_half_space(struct streamzap_ir *sz, sz_push_full_space(sz, value & SZ_SPACE_MASK); } -/* - * streamzap_callback - usb IRQ handler callback - * - * This procedure is invoked on reception of data from - * the usb remote. - */ -static void streamzap_callback(struct urb *urb) +static void sz_process_ir_data(struct streamzap_ir *sz, int len) { - struct streamzap_ir *sz; unsigned int i; - int len; - if (!urb) - return; - - sz = urb->context; - len = urb->actual_length; - - switch (urb->status) { - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* - * this urb is terminated, clean up. - * sz might already be invalid at this point - */ - dev_err(sz->dev, "urb terminated, status: %d\n", urb->status); - return; - default: - break; - } - - dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); for (i = 0; i < len; i++) { dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n", i, (unsigned char)sz->buf_in[i]); @@ -219,6 +190,43 @@ static void streamzap_callback(struct urb *urb) } ir_raw_event_handle(sz->rdev); +} + +/* + * streamzap_callback - usb IRQ handler callback + * + * This procedure is invoked on reception of data from + * the usb remote. + */ +static void streamzap_callback(struct urb *urb) +{ + struct streamzap_ir *sz; + int len; + + if (!urb) + return; + + sz = urb->context; + len = urb->actual_length; + + switch (urb->status) { + case 0: + dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); + sz_process_ir_data(sz, len); + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* + * this urb is terminated, clean up. + * sz might already be invalid at this point + */ + dev_err(sz->dev, "urb terminated, status: %d\n", urb->status); + return; + default: + break; + } + usb_submit_urb(urb, GFP_ATOMIC); } @@ -385,8 +393,8 @@ static void streamzap_disconnect(struct usb_interface *interface) if (!sz) return; - rc_unregister_device(sz->rdev); usb_kill_urb(sz->urb_in); + rc_unregister_device(sz->rdev); usb_free_urb(sz->urb_in); usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in); diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index bf58c965ead8..92ef4e7c6f69 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -12,6 +12,7 @@ #include <linux/clk.h> #include <linux/interrupt.h> +#include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -412,7 +413,7 @@ MODULE_DEVICE_TABLE(of, sunxi_ir_match); static struct platform_driver sunxi_ir_driver = { .probe = sunxi_ir_probe, - .remove_new = sunxi_ir_remove, + .remove = sunxi_ir_remove, .shutdown = sunxi_ir_shutdown, .driver = { .name = SUNXI_IR_DEV, |