aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorLinus Torvalds2021-09-01 10:34:52 -0700
committerLinus Torvalds2021-09-01 10:34:52 -0700
commit835d31d319d9c8c4eb6cac074643360ba0ecab10 (patch)
tree824dc6286c3f34357de0a0c12d0311eca9a6da8d /drivers/media/rc
parent0d290223a6c77107b1c3988959e49279a8dafaba (diff)
parent9c3a0f285248899dfa81585bc5d5bc9ebdb8fead (diff)
Merge tag 'media/v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - new sensor drivers: imx335, imx412, ov9282 - new IR transmitter driver: meson-ir-tx - handro driver gained support for H.264 for Rockchip VDPU2 - imx gained support for i.MX8MQ - ti-vpe has gained support for other SoC variants - lots of cleanups, fixes, board additions and doc improvements * tag 'media/v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (195 commits) media: venus: venc: add support for V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM control media: venus: venc: Add support for intra-refresh period media: v4l2-ctrls: Add intra-refresh period control media: docs: ext-ctrls-codec: Document cyclic intra-refresh zero control value media: venus: helper: do not set constrained parameters for UBWC media: venus: venc: Fix potential null pointer dereference on pointer fmt media: venus: hfi: fix return value check in sys_get_prop_image_version() media: tegra-cec: Handle errors of clk_prepare_enable() media: cec-pin: rename timer overrun variables media: TDA1997x: report -ENOLINK after disconnecting HDMI source media: TDA1997x: fix tda1997x_query_dv_timings() return value media: Fix cosmetic error in TDA1997x driver media: v4l2-dv-timings.c: fix wrong condition in two for-loops media: imx: add a driver for i.MX8MQ mipi csi rx phy and controller media: dt-bindings: media: document the nxp,imx8mq-mipi-csi2 receiver phy and controller media: imx: imx7_mipi_csis: convert some switch cases to the default media: imx: imx7-media-csi: Fix buffer return upon stream start failure media: imx: imx7-media-csi: Don't set PIXEL_BIT in CSICR1 media: imx: imx7-media-csi: Set TWO_8BIT_SENSOR for >= 10-bit formats media: dt-bindings: media: nxp,imx7-csi: Add i.MX8MM support ...
Diffstat (limited to 'drivers/media/rc')
-rw-r--r--drivers/media/rc/Kconfig10
-rw-r--r--drivers/media/rc/Makefile1
-rw-r--r--drivers/media/rc/ene_ir.c2
-rw-r--r--drivers/media/rc/lirc_dev.c6
-rw-r--r--drivers/media/rc/mceusb.c2
-rw-r--r--drivers/media/rc/meson-ir-tx.c407
-rw-r--r--drivers/media/rc/rc-loopback.c82
-rw-r--r--drivers/media/rc/rc-main.c2
-rw-r--r--drivers/media/rc/redrat3.c2
-rw-r--r--drivers/media/rc/streamzap.c2
10 files changed, 466 insertions, 50 deletions
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index d0a8326b75c2..fd5a7a058714 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -246,6 +246,16 @@ config IR_MESON
To compile this driver as a module, choose M here: the
module will be called meson-ir.
+config IR_MESON_TX
+ tristate "Amlogic Meson IR TX"
+ depends on ARCH_MESON || COMPILE_TEST
+ help
+ Say Y if you want to use the IR transmitter available on
+ Amlogic Meson SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called meson-ir-tx.
+
config IR_MTK
tristate "Mediatek IR remote receiver"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 692e9b6b203f..0db51fad27d6 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
obj-$(CONFIG_IR_MCEUSB) += mceusb.o
obj-$(CONFIG_IR_FINTEK) += fintek-cir.o
obj-$(CONFIG_IR_MESON) += meson-ir.o
+obj-$(CONFIG_IR_MESON_TX) += meson-ir-tx.o
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
obj-$(CONFIG_IR_ENE) += ene_ir.o
obj-$(CONFIG_IR_REDRAT3) += redrat3.o
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index 6049e5c95394..e09270916fbc 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -1052,7 +1052,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
rdev->device_name = "ENE eHome Infrared Remote Receiver";
if (dev->hw_learning_and_tx_capable) {
- rdev->s_learning_mode = ene_set_learning_mode;
+ rdev->s_wideband_receiver = ene_set_learning_mode;
init_completion(&dev->tx_complete);
rdev->tx_ir = ene_transmit;
rdev->s_tx_mask = ene_set_tx_mask;
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 116daf90c858..7f591ff5269d 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -412,7 +412,7 @@ static long lirc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
val |= LIRC_CAN_SET_REC_CARRIER |
LIRC_CAN_SET_REC_CARRIER_RANGE;
- if (dev->s_learning_mode)
+ if (dev->s_wideband_receiver)
val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
if (dev->s_carrier_report)
@@ -519,10 +519,10 @@ static long lirc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
case LIRC_SET_WIDEBAND_RECEIVER:
- if (!dev->s_learning_mode)
+ if (!dev->s_wideband_receiver)
ret = -ENOTTY;
else
- ret = dev->s_learning_mode(dev, !!val);
+ ret = dev->s_wideband_receiver(dev, !!val);
break;
case LIRC_SET_MEASURE_CARRIER_MODE:
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 5642595a057e..e03dd1f0144f 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1630,7 +1630,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
rc->tx_ir = mceusb_tx_ir;
}
if (ir->flags.rx2 > 0) {
- rc->s_learning_mode = mceusb_set_rx_wideband;
+ rc->s_wideband_receiver = mceusb_set_rx_wideband;
rc->s_carrier_report = mceusb_set_rx_carrier_report;
}
rc->driver_name = DRIVER_NAME;
diff --git a/drivers/media/rc/meson-ir-tx.c b/drivers/media/rc/meson-ir-tx.c
new file mode 100644
index 000000000000..3055f8e1b6ff
--- /dev/null
+++ b/drivers/media/rc/meson-ir-tx.c
@@ -0,0 +1,407 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/**
+ * meson-ir-tx.c - Amlogic Meson IR TX driver
+ *
+ * Copyright (c) 2021, SberDevices. All Rights Reserved.
+ *
+ * Author: Viktor Prutyanov <viktor.prutyanov@phystech.edu>
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/of_irq.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <media/rc-core.h>
+
+#define DEVICE_NAME "Meson IR TX"
+#define DRIVER_NAME "meson-ir-tx"
+
+#define MIRTX_DEFAULT_CARRIER 38000
+#define MIRTX_DEFAULT_DUTY_CYCLE 50
+#define MIRTX_FIFO_THD 32
+
+#define IRB_MOD_1US_CLK_RATE 1000000
+
+#define IRB_FIFO_LEN 128
+
+#define IRB_ADDR0 0x0
+#define IRB_ADDR1 0x4
+#define IRB_ADDR2 0x8
+#define IRB_ADDR3 0xc
+
+#define IRB_MAX_DELAY (1 << 10)
+#define IRB_DELAY_MASK (IRB_MAX_DELAY - 1)
+
+/* IRCTRL_IR_BLASTER_ADDR0 */
+#define IRB_MOD_CLK(x) ((x) << 12)
+#define IRB_MOD_SYS_CLK 0
+#define IRB_MOD_XTAL3_CLK 1
+#define IRB_MOD_1US_CLK 2
+#define IRB_MOD_10US_CLK 3
+#define IRB_INIT_HIGH BIT(2)
+#define IRB_ENABLE BIT(0)
+
+/* IRCTRL_IR_BLASTER_ADDR2 */
+#define IRB_MOD_COUNT(lo, hi) ((((lo) - 1) << 16) | ((hi) - 1))
+
+/* IRCTRL_IR_BLASTER_ADDR2 */
+#define IRB_WRITE_FIFO BIT(16)
+#define IRB_MOD_ENABLE BIT(12)
+#define IRB_TB_1US (0x0 << 10)
+#define IRB_TB_10US (0x1 << 10)
+#define IRB_TB_100US (0x2 << 10)
+#define IRB_TB_MOD_CLK (0x3 << 10)
+
+/* IRCTRL_IR_BLASTER_ADDR3 */
+#define IRB_FIFO_THD_PENDING BIT(16)
+#define IRB_FIFO_IRQ_ENABLE BIT(8)
+
+struct meson_irtx {
+ struct device *dev;
+ void __iomem *reg_base;
+ u32 *buf;
+ unsigned int buf_len;
+ unsigned int buf_head;
+ unsigned int carrier;
+ unsigned int duty_cycle;
+ /* Locks buf */
+ spinlock_t lock;
+ struct completion completion;
+ unsigned long clk_rate;
+};
+
+static void meson_irtx_set_mod(struct meson_irtx *ir)
+{
+ unsigned int cnt = DIV_ROUND_CLOSEST(ir->clk_rate, ir->carrier);
+ unsigned int pulse_cnt = DIV_ROUND_CLOSEST(cnt * ir->duty_cycle, 100);
+ unsigned int space_cnt = cnt - pulse_cnt;
+
+ dev_dbg(ir->dev, "F_mod = %uHz, T_mod = %luns, duty_cycle = %u%%\n",
+ ir->carrier, NSEC_PER_SEC / ir->clk_rate * cnt,
+ 100 * pulse_cnt / cnt);
+
+ writel(IRB_MOD_COUNT(pulse_cnt, space_cnt),
+ ir->reg_base + IRB_ADDR1);
+}
+
+static void meson_irtx_setup(struct meson_irtx *ir, unsigned int clk_nr)
+{
+ /*
+ * Disable the TX, set modulator clock tick and set initialize
+ * output to be high. Set up carrier frequency and duty cycle. Then
+ * unset initialize output. Enable FIFO interrupt, set FIFO interrupt
+ * threshold. Finally, enable the transmitter back.
+ */
+ writel(~IRB_ENABLE & (IRB_MOD_CLK(clk_nr) | IRB_INIT_HIGH),
+ ir->reg_base + IRB_ADDR0);
+ meson_irtx_set_mod(ir);
+ writel(readl(ir->reg_base + IRB_ADDR0) & ~IRB_INIT_HIGH,
+ ir->reg_base + IRB_ADDR0);
+ writel(IRB_FIFO_IRQ_ENABLE | MIRTX_FIFO_THD,
+ ir->reg_base + IRB_ADDR3);
+ writel(readl(ir->reg_base + IRB_ADDR0) | IRB_ENABLE,
+ ir->reg_base + IRB_ADDR0);
+}
+
+static u32 meson_irtx_prepare_pulse(struct meson_irtx *ir, unsigned int time)
+{
+ unsigned int delay;
+ unsigned int tb = IRB_TB_MOD_CLK;
+ unsigned int tb_us = DIV_ROUND_CLOSEST(USEC_PER_SEC, ir->carrier);
+
+ delay = (DIV_ROUND_CLOSEST(time, tb_us) - 1) & IRB_DELAY_MASK;
+
+ return ((IRB_WRITE_FIFO | IRB_MOD_ENABLE) | tb | delay);
+}
+
+static u32 meson_irtx_prepare_space(struct meson_irtx *ir, unsigned int time)
+{
+ unsigned int delay;
+ unsigned int tb = IRB_TB_100US;
+ unsigned int tb_us = 100;
+
+ if (time <= IRB_MAX_DELAY) {
+ tb = IRB_TB_1US;
+ tb_us = 1;
+ } else if (time <= 10 * IRB_MAX_DELAY) {
+ tb = IRB_TB_10US;
+ tb_us = 10;
+ } else if (time <= 100 * IRB_MAX_DELAY) {
+ tb = IRB_TB_100US;
+ tb_us = 100;
+ }
+
+ delay = (DIV_ROUND_CLOSEST(time, tb_us) - 1) & IRB_DELAY_MASK;
+
+ return ((IRB_WRITE_FIFO & ~IRB_MOD_ENABLE) | tb | delay);
+}
+
+static void meson_irtx_send_buffer(struct meson_irtx *ir)
+{
+ unsigned int nr = 0;
+ unsigned int max_fifo_level = IRB_FIFO_LEN - MIRTX_FIFO_THD;
+
+ while (ir->buf_head < ir->buf_len && nr < max_fifo_level) {
+ writel(ir->buf[ir->buf_head], ir->reg_base + IRB_ADDR2);
+
+ ir->buf_head++;
+ nr++;
+ }
+}
+
+static bool meson_irtx_check_buf(struct meson_irtx *ir,
+ unsigned int *buf, unsigned int len)
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++) {
+ unsigned int max_tb_us;
+ /*
+ * Max space timebase is 100 us.
+ * Pulse timebase equals to carrier period.
+ */
+ if (i % 2 == 0)
+ max_tb_us = USEC_PER_SEC / ir->carrier;
+ else
+ max_tb_us = 100;
+
+ if (buf[i] >= max_tb_us * IRB_MAX_DELAY)
+ return false;
+ }
+
+ return true;
+}
+
+static void meson_irtx_fill_buf(struct meson_irtx *ir, u32 *dst_buf,
+ unsigned int *src_buf, unsigned int len)
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++) {
+ if (i % 2 == 0)
+ dst_buf[i] = meson_irtx_prepare_pulse(ir, src_buf[i]);
+ else
+ dst_buf[i] = meson_irtx_prepare_space(ir, src_buf[i]);
+ }
+}
+
+static irqreturn_t meson_irtx_irqhandler(int irq, void *data)
+{
+ unsigned long flags;
+ struct meson_irtx *ir = data;
+
+ writel(readl(ir->reg_base + IRB_ADDR3) & ~IRB_FIFO_THD_PENDING,
+ ir->reg_base + IRB_ADDR3);
+
+ if (completion_done(&ir->completion))
+ return IRQ_HANDLED;
+
+ spin_lock_irqsave(&ir->lock, flags);
+ if (ir->buf_head < ir->buf_len)
+ meson_irtx_send_buffer(ir);
+ else
+ complete(&ir->completion);
+ spin_unlock_irqrestore(&ir->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static int meson_irtx_set_carrier(struct rc_dev *rc, u32 carrier)
+{
+ struct meson_irtx *ir = rc->priv;
+
+ if (carrier == 0)
+ return -EINVAL;
+
+ ir->carrier = carrier;
+ meson_irtx_set_mod(ir);
+
+ return 0;
+}
+
+static int meson_irtx_set_duty_cycle(struct rc_dev *rc, u32 duty_cycle)
+{
+ struct meson_irtx *ir = rc->priv;
+
+ ir->duty_cycle = duty_cycle;
+ meson_irtx_set_mod(ir);
+
+ return 0;
+}
+
+static void meson_irtx_update_buf(struct meson_irtx *ir, u32 *buf,
+ unsigned int len, unsigned int head)
+{
+ ir->buf = buf;
+ ir->buf_len = len;
+ ir->buf_head = head;
+}
+
+static int meson_irtx_transmit(struct rc_dev *rc, unsigned int *buf,
+ unsigned int len)
+{
+ unsigned long flags;
+ struct meson_irtx *ir = rc->priv;
+ u32 *tx_buf;
+ int ret = len;
+
+ if (!meson_irtx_check_buf(ir, buf, len))
+ return -EINVAL;
+
+ tx_buf = kmalloc_array(len, sizeof(u32), GFP_KERNEL);
+ if (!tx_buf)
+ return -ENOMEM;
+
+ meson_irtx_fill_buf(ir, tx_buf, buf, len);
+ dev_dbg(ir->dev, "TX buffer filled, length = %u\n", len);
+
+ spin_lock_irqsave(&ir->lock, flags);
+ meson_irtx_update_buf(ir, tx_buf, len, 0);
+ reinit_completion(&ir->completion);
+ meson_irtx_send_buffer(ir);
+ spin_unlock_irqrestore(&ir->lock, flags);
+
+ if (!wait_for_completion_timeout(&ir->completion,
+ usecs_to_jiffies(IR_MAX_DURATION)))
+ ret = -ETIMEDOUT;
+
+ spin_lock_irqsave(&ir->lock, flags);
+ kfree(ir->buf);
+ meson_irtx_update_buf(ir, NULL, 0, 0);
+ spin_unlock_irqrestore(&ir->lock, flags);
+
+ return ret;
+}
+
+static int meson_irtx_mod_clock_probe(struct meson_irtx *ir,
+ unsigned int *clk_nr)
+{
+ struct device_node *np = ir->dev->of_node;
+ struct clk *clock;
+
+ if (!np)
+ return -ENODEV;
+
+ clock = devm_clk_get(ir->dev, "xtal");
+ if (IS_ERR(clock) || clk_prepare_enable(clock))
+ return -ENODEV;
+
+ *clk_nr = IRB_MOD_XTAL3_CLK;
+ ir->clk_rate = clk_get_rate(clock) / 3;
+
+ if (ir->clk_rate < IRB_MOD_1US_CLK_RATE) {
+ *clk_nr = IRB_MOD_1US_CLK;
+ ir->clk_rate = IRB_MOD_1US_CLK_RATE;
+ }
+
+ dev_info(ir->dev, "F_clk = %luHz\n", ir->clk_rate);
+
+ return 0;
+}
+
+static int __init meson_irtx_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct meson_irtx *ir;
+ struct rc_dev *rc;
+ int irq;
+ unsigned int clk_nr;
+ int ret;
+
+ ir = devm_kzalloc(dev, sizeof(*ir), GFP_KERNEL);
+ if (!ir)
+ return -ENOMEM;
+
+ ir->reg_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ir->reg_base))
+ return PTR_ERR(ir->reg_base);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "no irq resource found\n");
+ return -ENODEV;
+ }
+
+ ir->dev = dev;
+ ir->carrier = MIRTX_DEFAULT_CARRIER;
+ ir->duty_cycle = MIRTX_DEFAULT_DUTY_CYCLE;
+ init_completion(&ir->completion);
+ spin_lock_init(&ir->lock);
+
+ ret = meson_irtx_mod_clock_probe(ir, &clk_nr);
+ if (ret) {
+ dev_err(dev, "modulator clock setup failed\n");
+ return ret;
+ }
+ meson_irtx_setup(ir, clk_nr);
+
+ ret = devm_request_irq(dev, irq,
+ meson_irtx_irqhandler,
+ IRQF_TRIGGER_RISING,
+ DRIVER_NAME, ir);
+ if (ret) {
+ dev_err(dev, "irq request failed\n");
+ return ret;
+ }
+
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW_TX);
+ if (!rc)
+ return -ENOMEM;
+
+ rc->driver_name = DRIVER_NAME;
+ rc->device_name = DEVICE_NAME;
+ rc->priv = ir;
+
+ rc->tx_ir = meson_irtx_transmit;
+ rc->s_tx_carrier = meson_irtx_set_carrier;
+ rc->s_tx_duty_cycle = meson_irtx_set_duty_cycle;
+
+ ret = rc_register_device(rc);
+ if (ret < 0) {
+ dev_err(dev, "rc_dev registration failed\n");
+ rc_free_device(rc);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, rc);
+
+ return 0;
+}
+
+static int meson_irtx_remove(struct platform_device *pdev)
+{
+ struct rc_dev *rc = platform_get_drvdata(pdev);
+
+ rc_unregister_device(rc);
+
+ return 0;
+}
+
+static const struct of_device_id meson_irtx_dt_match[] = {
+ {
+ .compatible = "amlogic,meson-g12a-ir-tx",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, meson_irtx_dt_match);
+
+static struct platform_driver meson_irtx_pd = {
+ .remove = meson_irtx_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = meson_irtx_dt_match,
+ },
+};
+
+module_platform_driver_probe(meson_irtx_pd, meson_irtx_probe);
+
+MODULE_DESCRIPTION("Meson IR TX driver");
+MODULE_AUTHOR("Viktor Prutyanov <viktor.prutyanov@phystech.edu>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index 1ba3f96ffa7d..6441879fcba1 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -15,12 +15,9 @@
#include <linux/slab.h>
#include <media/rc-core.h>
-#define DRIVER_NAME "rc-loopback"
-#define dprintk(x...) if (debug) printk(KERN_INFO DRIVER_NAME ": " x)
-#define RXMASK_REGULAR 0x1
-#define RXMASK_LEARNING 0x2
-
-static bool debug;
+#define DRIVER_NAME "rc-loopback"
+#define RXMASK_NARROWBAND 0x1
+#define RXMASK_WIDEBAND 0x2
struct loopback_dev {
struct rc_dev *dev;
@@ -28,7 +25,7 @@ struct loopback_dev {
u32 txcarrier;
u32 txduty;
bool idle;
- bool learning;
+ bool wideband;
bool carrierreport;
u32 rxcarriermin;
u32 rxcarriermax;
@@ -40,12 +37,12 @@ static int loop_set_tx_mask(struct rc_dev *dev, u32 mask)
{
struct loopback_dev *lodev = dev->priv;
- if ((mask & (RXMASK_REGULAR | RXMASK_LEARNING)) != mask) {
- dprintk("invalid tx mask: %u\n", mask);
- return -EINVAL;
+ if ((mask & (RXMASK_NARROWBAND | RXMASK_WIDEBAND)) != mask) {
+ dev_dbg(&dev->dev, "invalid tx mask: %u\n", mask);
+ return 2;
}
- dprintk("setting tx mask: %u\n", mask);
+ dev_dbg(&dev->dev, "setting tx mask: %u\n", mask);
lodev->txmask = mask;
return 0;
}
@@ -54,7 +51,7 @@ static int loop_set_tx_carrier(struct rc_dev *dev, u32 carrier)
{
struct loopback_dev *lodev = dev->priv;
- dprintk("setting tx carrier: %u\n", carrier);
+ dev_dbg(&dev->dev, "setting tx carrier: %u\n", carrier);
lodev->txcarrier = carrier;
return 0;
}
@@ -64,11 +61,11 @@ static int loop_set_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
struct loopback_dev *lodev = dev->priv;
if (duty_cycle < 1 || duty_cycle > 99) {
- dprintk("invalid duty cycle: %u\n", duty_cycle);
+ dev_dbg(&dev->dev, "invalid duty cycle: %u\n", duty_cycle);
return -EINVAL;
}
- dprintk("setting duty cycle: %u\n", duty_cycle);
+ dev_dbg(&dev->dev, "setting duty cycle: %u\n", duty_cycle);
lodev->txduty = duty_cycle;
return 0;
}
@@ -78,11 +75,11 @@ static int loop_set_rx_carrier_range(struct rc_dev *dev, u32 min, u32 max)
struct loopback_dev *lodev = dev->priv;
if (min < 1 || min > max) {
- dprintk("invalid rx carrier range %u to %u\n", min, max);
+ dev_dbg(&dev->dev, "invalid rx carrier range %u to %u\n", min, max);
return -EINVAL;
}
- dprintk("setting rx carrier range %u to %u\n", min, max);
+ dev_dbg(&dev->dev, "setting rx carrier range %u to %u\n", min, max);
lodev->rxcarriermin = min;
lodev->rxcarriermax = max;
return 0;
@@ -97,25 +94,33 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
if (lodev->txcarrier < lodev->rxcarriermin ||
lodev->txcarrier > lodev->rxcarriermax) {
- dprintk("ignoring tx, carrier out of range\n");
+ dev_dbg(&dev->dev, "ignoring tx, carrier out of range\n");
goto out;
}
- if (lodev->learning)
- rxmask = RXMASK_LEARNING;
+ if (lodev->wideband)
+ rxmask = RXMASK_WIDEBAND;
else
- rxmask = RXMASK_REGULAR;
+ rxmask = RXMASK_NARROWBAND;
if (!(rxmask & lodev->txmask)) {
- dprintk("ignoring tx, rx mask mismatch\n");
+ dev_dbg(&dev->dev, "ignoring tx, rx mask mismatch\n");
goto out;
}
for (i = 0; i < count; i++) {
rawir.pulse = i % 2 ? false : true;
rawir.duration = txbuf[i];
- if (rawir.duration)
- ir_raw_event_store_with_filter(dev, &rawir);
+
+ ir_raw_event_store_with_filter(dev, &rawir);
+ }
+
+ if (lodev->carrierreport) {
+ rawir.pulse = false;
+ rawir.carrier_report = true;
+ rawir.carrier = lodev->txcarrier;
+
+ ir_raw_event_store(dev, &rawir);
}
/* Fake a silence long enough to cause us to go idle */
@@ -134,18 +139,18 @@ static void loop_set_idle(struct rc_dev *dev, bool enable)
struct loopback_dev *lodev = dev->priv;
if (lodev->idle != enable) {
- dprintk("%sing idle mode\n", enable ? "enter" : "exit");
+ dev_dbg(&dev->dev, "%sing idle mode\n", enable ? "enter" : "exit");
lodev->idle = enable;
}
}
-static int loop_set_learning_mode(struct rc_dev *dev, int enable)
+static int loop_set_wideband_receiver(struct rc_dev *dev, int enable)
{
struct loopback_dev *lodev = dev->priv;
- if (lodev->learning != enable) {
- dprintk("%sing learning mode\n", enable ? "enter" : "exit");
- lodev->learning = !!enable;
+ if (lodev->wideband != enable) {
+ dev_dbg(&dev->dev, "using %sband receiver\n", enable ? "wide" : "narrow");
+ lodev->wideband = !!enable;
}
return 0;
@@ -156,7 +161,7 @@ static int loop_set_carrier_report(struct rc_dev *dev, int enable)
struct loopback_dev *lodev = dev->priv;
if (lodev->carrierreport != enable) {
- dprintk("%sabling carrier reports\n", enable ? "en" : "dis");
+ dev_dbg(&dev->dev, "%sabling carrier reports\n", enable ? "en" : "dis");
lodev->carrierreport = !!enable;
}
@@ -204,10 +209,8 @@ static int __init loop_init(void)
int ret;
rc = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rc) {
- printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
+ if (!rc)
return -ENOMEM;
- }
rc->device_name = "rc-core loopback device";
rc->input_phys = "rc-core/virtual";
@@ -219,9 +222,9 @@ static int __init loop_init(void)
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 = MS_TO_US(100); /* 100 ms */
+ rc->timeout = IR_DEFAULT_TIMEOUT;
rc->min_timeout = 1;
- rc->max_timeout = UINT_MAX;
+ rc->max_timeout = IR_MAX_TIMEOUT;
rc->rx_resolution = 1;
rc->tx_resolution = 1;
rc->s_tx_mask = loop_set_tx_mask;
@@ -230,22 +233,22 @@ static int __init loop_init(void)
rc->s_rx_carrier_range = loop_set_rx_carrier_range;
rc->tx_ir = loop_tx_ir;
rc->s_idle = loop_set_idle;
- rc->s_learning_mode = loop_set_learning_mode;
+ rc->s_wideband_receiver = loop_set_wideband_receiver;
rc->s_carrier_report = loop_set_carrier_report;
rc->s_wakeup_filter = loop_set_wakeup_filter;
- loopdev.txmask = RXMASK_REGULAR;
+ loopdev.txmask = RXMASK_NARROWBAND;
loopdev.txcarrier = 36000;
loopdev.txduty = 50;
loopdev.rxcarriermin = 1;
loopdev.rxcarriermax = ~0;
loopdev.idle = true;
- loopdev.learning = false;
+ loopdev.wideband = false;
loopdev.carrierreport = false;
ret = rc_register_device(rc);
if (ret < 0) {
- printk(KERN_ERR DRIVER_NAME ": rc_dev registration failed\n");
+ dev_err(&rc->dev, "rc_dev registration failed\n");
rc_free_device(rc);
return ret;
}
@@ -262,9 +265,6 @@ static void __exit loop_exit(void)
module_init(loop_init);
module_exit(loop_exit);
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Enable debug messages");
-
MODULE_DESCRIPTION("Loopback device for rc-core debugging");
MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 8e88dc8ea6c5..b90438a71c80 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1940,7 +1940,7 @@ int rc_register_device(struct rc_dev *dev)
kfree(path);
/*
- * once the the input device is registered in rc_setup_rx_device,
+ * once the input device is registered in rc_setup_rx_device,
* userspace can open the input device and rc_open() will be called
* as a result. This results in driver code being allowed to submit
* keycodes with rc_keydown, so lirc must be registered first.
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 2cf3377ec63a..ac85464864b9 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -6,7 +6,7 @@
* based heavily on the work of Stephen Cox, with additional
* help from RedRat Ltd.
*
- * This driver began life based an an old version of the first-generation
+ * This driver began life based on an old version of the first-generation
* lirc_mceusb driver from the lirc 0.7.2 distribution. It was then
* significantly rewritten by Stephen Cox with the aid of RedRat Ltd's
* Chris Dodge.
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index 9f3cd9fb6b6e..9cd765e31c49 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -265,8 +265,6 @@ static void streamzap_callback(struct urb *urb)
ir_raw_event_handle(sz->rdev);
usb_submit_urb(urb, GFP_ATOMIC);
-
- return;
}
static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)