mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
1035 lines
30 KiB
Diff
1035 lines
30 KiB
Diff
|
From 6e0336d1660725c06b6ab4f5361873538dbaa9f9 Mon Sep 17 00:00:00 2001
|
||
|
From: Sean Wang <sean.wang@mediatek.com>
|
||
|
Date: Fri, 13 Jan 2017 15:35:39 +0800
|
||
|
Subject: [PATCH 24/57] media: rc: add driver for IR remote receiver on MT7623
|
||
|
SoC
|
||
|
|
||
|
This patch adds driver for IR controller on MT7623 SoC.
|
||
|
and should also work on similar Mediatek SoC. Currently
|
||
|
testing successfully on NEC and SONY remote controller
|
||
|
only but it should work on others (lirc, rc-5 and rc-6).
|
||
|
|
||
|
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
|
||
|
Reviewed-by: Sean Young <sean@mess.org>
|
||
|
---
|
||
|
drivers/media/rc/Kconfig | 11 ++
|
||
|
drivers/media/rc/mtk-cir.c | 329 +++++++++++++++++++++++++++++++++++++++++++++
|
||
|
2 files changed, 340 insertions(+)
|
||
|
create mode 100644 drivers/media/rc/mtk-cir.c
|
||
|
|
||
|
--- a/drivers/media/rc/Kconfig
|
||
|
+++ b/drivers/media/rc/Kconfig
|
||
|
@@ -235,6 +235,17 @@ config IR_MESON
|
||
|
To compile this driver as a module, choose M here: the
|
||
|
module will be called meson-ir.
|
||
|
|
||
|
+config IR_MTK
|
||
|
+ tristate "Mediatek IR remote receiver"
|
||
|
+ depends on RC_CORE
|
||
|
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||
|
+ ---help---
|
||
|
+ Say Y if you want to use the IR remote receiver available
|
||
|
+ on Mediatek SoCs.
|
||
|
+
|
||
|
+ To compile this driver as a module, choose M here: the
|
||
|
+ module will be called mtk-cir.
|
||
|
+
|
||
|
config IR_NUVOTON
|
||
|
tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
|
||
|
depends on PNP
|
||
|
--- /dev/null
|
||
|
+++ b/drivers/media/rc/mtk-cir.c
|
||
|
@@ -0,0 +1,329 @@
|
||
|
+/*
|
||
|
+ * Driver for Mediatek IR Receiver Controller
|
||
|
+ *
|
||
|
+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
|
||
|
+ *
|
||
|
+ * This program is free software; you can redistribute it and/or
|
||
|
+ * modify it under the terms of the GNU General Public License as
|
||
|
+ * published by the Free Software Foundation; either version 2 of
|
||
|
+ * the License, or (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This program is distributed in the hope that it will be useful,
|
||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License for more details.
|
||
|
+ */
|
||
|
+
|
||
|
+#include <linux/clk.h>
|
||
|
+#include <linux/interrupt.h>
|
||
|
+#include <linux/module.h>
|
||
|
+#include <linux/of_platform.h>
|
||
|
+#include <linux/reset.h>
|
||
|
+#include <media/rc-core.h>
|
||
|
+
|
||
|
+#define MTK_IR_DEV KBUILD_MODNAME
|
||
|
+
|
||
|
+/* Register to enable PWM and IR */
|
||
|
+#define MTK_CONFIG_HIGH_REG 0x0c
|
||
|
+/* Enable IR pulse width detection */
|
||
|
+#define MTK_PWM_EN BIT(13)
|
||
|
+/* Enable IR hardware function */
|
||
|
+#define MTK_IR_EN BIT(0)
|
||
|
+
|
||
|
+/* Register to setting sample period */
|
||
|
+#define MTK_CONFIG_LOW_REG 0x10
|
||
|
+/* Field to set sample period */
|
||
|
+#define CHK_PERIOD DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, \
|
||
|
+ MTK_IR_CLK_PERIOD)
|
||
|
+#define MTK_CHK_PERIOD (((CHK_PERIOD) << 8) & (GENMASK(20, 8)))
|
||
|
+#define MTK_CHK_PERIOD_MASK (GENMASK(20, 8))
|
||
|
+
|
||
|
+/* Register to clear state of state machine */
|
||
|
+#define MTK_IRCLR_REG 0x20
|
||
|
+/* Bit to restart IR receiving */
|
||
|
+#define MTK_IRCLR BIT(0)
|
||
|
+
|
||
|
+/* Register containing pulse width data */
|
||
|
+#define MTK_CHKDATA_REG(i) (0x88 + 4 * (i))
|
||
|
+#define MTK_WIDTH_MASK (GENMASK(7, 0))
|
||
|
+
|
||
|
+/* Register to enable IR interrupt */
|
||
|
+#define MTK_IRINT_EN_REG 0xcc
|
||
|
+/* Bit to enable interrupt */
|
||
|
+#define MTK_IRINT_EN BIT(0)
|
||
|
+
|
||
|
+/* Register to ack IR interrupt */
|
||
|
+#define MTK_IRINT_CLR_REG 0xd0
|
||
|
+/* Bit to clear interrupt status */
|
||
|
+#define MTK_IRINT_CLR BIT(0)
|
||
|
+
|
||
|
+/* Maximum count of samples */
|
||
|
+#define MTK_MAX_SAMPLES 0xff
|
||
|
+/* Indicate the end of IR message */
|
||
|
+#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
|
||
|
+/* Source clock frequency */
|
||
|
+#define MTK_IR_BASE_CLK 273000000
|
||
|
+/* Frequency after IR internal divider */
|
||
|
+#define MTK_IR_CLK_FREQ (MTK_IR_BASE_CLK / 4)
|
||
|
+/* Period for MTK_IR_CLK in ns*/
|
||
|
+#define MTK_IR_CLK_PERIOD DIV_ROUND_CLOSEST(1000000000ul, \
|
||
|
+ MTK_IR_CLK_FREQ)
|
||
|
+/* Sample period in ns */
|
||
|
+#define MTK_IR_SAMPLE (MTK_IR_CLK_PERIOD * 0xc00)
|
||
|
+
|
||
|
+/* struct mtk_ir - This is the main datasructure for holding the state
|
||
|
+ * of the driver
|
||
|
+ * @dev: The device pointer
|
||
|
+ * @rc: The rc instrance
|
||
|
+ * @irq: The IRQ that we are using
|
||
|
+ * @base: The mapped register i/o base
|
||
|
+ * @clk: The clock that we are using
|
||
|
+ */
|
||
|
+struct mtk_ir {
|
||
|
+ struct device *dev;
|
||
|
+ struct rc_dev *rc;
|
||
|
+ void __iomem *base;
|
||
|
+ int irq;
|
||
|
+ struct clk *clk;
|
||
|
+};
|
||
|
+
|
||
|
+static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg)
|
||
|
+{
|
||
|
+ u32 tmp;
|
||
|
+
|
||
|
+ tmp = __raw_readl(ir->base + reg);
|
||
|
+ tmp = (tmp & ~mask) | val;
|
||
|
+ __raw_writel(tmp, ir->base + reg);
|
||
|
+}
|
||
|
+
|
||
|
+static void mtk_w32(struct mtk_ir *ir, u32 val, unsigned int reg)
|
||
|
+{
|
||
|
+ __raw_writel(val, ir->base + reg);
|
||
|
+}
|
||
|
+
|
||
|
+static u32 mtk_r32(struct mtk_ir *ir, unsigned int reg)
|
||
|
+{
|
||
|
+ return __raw_readl(ir->base + reg);
|
||
|
+}
|
||
|
+
|
||
|
+static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask)
|
||
|
+{
|
||
|
+ u32 val;
|
||
|
+
|
||
|
+ val = mtk_r32(ir, MTK_IRINT_EN_REG);
|
||
|
+ mtk_w32(ir, val & ~mask, MTK_IRINT_EN_REG);
|
||
|
+}
|
||
|
+
|
||
|
+static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask)
|
||
|
+{
|
||
|
+ u32 val;
|
||
|
+
|
||
|
+ val = mtk_r32(ir, MTK_IRINT_EN_REG);
|
||
|
+ mtk_w32(ir, val | mask, MTK_IRINT_EN_REG);
|
||
|
+}
|
||
|
+
|
||
|
+static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
|
||
|
+{
|
||
|
+ struct mtk_ir *ir = dev_id;
|
||
|
+ u8 wid = 0;
|
||
|
+ u32 i, j, val;
|
||
|
+ DEFINE_IR_RAW_EVENT(rawir);
|
||
|
+
|
||
|
+ /* Reset decoder state machine explicitly is required
|
||
|
+ * because 1) the longest duration for space MTK IR hardware
|
||
|
+ * could record is not safely long. e.g 12ms if rx resolution
|
||
|
+ * is 46us by default. There is still the risk to satisfying
|
||
|
+ * every decoder to reset themselves through long enough
|
||
|
+ * trailing spaces and 2) the IRQ handler guarantees that
|
||
|
+ * start of IR message is always contained in and starting
|
||
|
+ * from register MTK_CHKDATA_REG(0).
|
||
|
+ */
|
||
|
+ ir_raw_event_reset(ir->rc);
|
||
|
+
|
||
|
+ /* First message must be pulse */
|
||
|
+ rawir.pulse = false;
|
||
|
+
|
||
|
+ /* Handle all pulse and space IR controller captures */
|
||
|
+ for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
|
||
|
+ val = mtk_r32(ir, MTK_CHKDATA_REG(i));
|
||
|
+ dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);
|
||
|
+
|
||
|
+ for (j = 0 ; j < 4 ; j++) {
|
||
|
+ wid = (val & (MTK_WIDTH_MASK << j * 8)) >> j * 8;
|
||
|
+ rawir.pulse = !rawir.pulse;
|
||
|
+ rawir.duration = wid * (MTK_IR_SAMPLE + 1);
|
||
|
+ ir_raw_event_store_with_filter(ir->rc, &rawir);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* The maximum number of edges the IR controller can
|
||
|
+ * hold is MTK_CHKDATA_SZ * 4. So if received IR messages
|
||
|
+ * is over the limit, the last incomplete IR message would
|
||
|
+ * be appended trailing space and still would be sent into
|
||
|
+ * ir-rc-raw to decode. That helps it is possible that it
|
||
|
+ * has enough information to decode a scancode even if the
|
||
|
+ * trailing end of the message is missing.
|
||
|
+ */
|
||
|
+ if (!MTK_IR_END(wid, rawir.pulse)) {
|
||
|
+ rawir.pulse = false;
|
||
|
+ rawir.duration = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
|
||
|
+ ir_raw_event_store_with_filter(ir->rc, &rawir);
|
||
|
+ }
|
||
|
+
|
||
|
+ ir_raw_event_handle(ir->rc);
|
||
|
+
|
||
|
+ /* Restart controller for the next receive that would
|
||
|
+ * clear up all CHKDATA registers
|
||
|
+ */
|
||
|
+ mtk_w32_mask(ir, 0x1, MTK_IRCLR, MTK_IRCLR_REG);
|
||
|
+
|
||
|
+ /* Clear interrupt status */
|
||
|
+ mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, MTK_IRINT_CLR_REG);
|
||
|
+
|
||
|
+ return IRQ_HANDLED;
|
||
|
+}
|
||
|
+
|
||
|
+static int mtk_ir_probe(struct platform_device *pdev)
|
||
|
+{
|
||
|
+ struct device *dev = &pdev->dev;
|
||
|
+ struct device_node *dn = dev->of_node;
|
||
|
+ struct resource *res;
|
||
|
+ struct mtk_ir *ir;
|
||
|
+ u32 val;
|
||
|
+ int ret = 0;
|
||
|
+ const char *map_name;
|
||
|
+
|
||
|
+ ir = devm_kzalloc(dev, sizeof(struct mtk_ir), GFP_KERNEL);
|
||
|
+ if (!ir)
|
||
|
+ return -ENOMEM;
|
||
|
+
|
||
|
+ ir->dev = dev;
|
||
|
+
|
||
|
+ if (!of_device_is_compatible(dn, "mediatek,mt7623-cir"))
|
||
|
+ return -ENODEV;
|
||
|
+
|
||
|
+ ir->clk = devm_clk_get(dev, "clk");
|
||
|
+ if (IS_ERR(ir->clk)) {
|
||
|
+ dev_err(dev, "failed to get a ir clock.\n");
|
||
|
+ return PTR_ERR(ir->clk);
|
||
|
+ }
|
||
|
+
|
||
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||
|
+ ir->base = devm_ioremap_resource(dev, res);
|
||
|
+ if (IS_ERR(ir->base)) {
|
||
|
+ dev_err(dev, "failed to map registers\n");
|
||
|
+ return PTR_ERR(ir->base);
|
||
|
+ }
|
||
|
+
|
||
|
+ ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
|
||
|
+ if (!ir->rc) {
|
||
|
+ dev_err(dev, "failed to allocate device\n");
|
||
|
+ return -ENOMEM;
|
||
|
+ }
|
||
|
+
|
||
|
+ ir->rc->priv = ir;
|
||
|
+ ir->rc->input_name = MTK_IR_DEV;
|
||
|
+ ir->rc->input_phys = MTK_IR_DEV "/input0";
|
||
|
+ ir->rc->input_id.bustype = BUS_HOST;
|
||
|
+ ir->rc->input_id.vendor = 0x0001;
|
||
|
+ ir->rc->input_id.product = 0x0001;
|
||
|
+ ir->rc->input_id.version = 0x0001;
|
||
|
+ map_name = of_get_property(dn, "linux,rc-map-name", NULL);
|
||
|
+ ir->rc->map_name = map_name ?: RC_MAP_EMPTY;
|
||
|
+ ir->rc->dev.parent = dev;
|
||
|
+ ir->rc->driver_name = MTK_IR_DEV;
|
||
|
+ ir->rc->allowed_protocols = RC_BIT_ALL;
|
||
|
+ ir->rc->rx_resolution = MTK_IR_SAMPLE;
|
||
|
+ ir->rc->timeout = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
|
||
|
+
|
||
|
+ ret = devm_rc_register_device(dev, ir->rc);
|
||
|
+ if (ret) {
|
||
|
+ dev_err(dev, "failed to register rc device\n");
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
+
|
||
|
+ platform_set_drvdata(pdev, ir);
|
||
|
+
|
||
|
+ ir->irq = platform_get_irq(pdev, 0);
|
||
|
+ if (ir->irq < 0) {
|
||
|
+ dev_err(dev, "no irq resource\n");
|
||
|
+ return -ENODEV;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Enable interrupt after proper hardware
|
||
|
+ * setup and IRQ handler registration
|
||
|
+ */
|
||
|
+ if (clk_prepare_enable(ir->clk)) {
|
||
|
+ dev_err(dev, "try to enable ir_clk failed\n");
|
||
|
+ ret = -EINVAL;
|
||
|
+ goto exit_clkdisable_clk;
|
||
|
+ }
|
||
|
+
|
||
|
+ mtk_irq_disable(ir, MTK_IRINT_EN);
|
||
|
+
|
||
|
+ ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir);
|
||
|
+ if (ret) {
|
||
|
+ dev_err(dev, "failed request irq\n");
|
||
|
+ goto exit_clkdisable_clk;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Enable IR and PWM */
|
||
|
+ val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
|
||
|
+ val |= MTK_PWM_EN | MTK_IR_EN;
|
||
|
+ mtk_w32(ir, val, MTK_CONFIG_HIGH_REG);
|
||
|
+
|
||
|
+ /* Setting sample period */
|
||
|
+ mtk_w32_mask(ir, MTK_CHK_PERIOD, MTK_CHK_PERIOD_MASK,
|
||
|
+ MTK_CONFIG_LOW_REG);
|
||
|
+
|
||
|
+ mtk_irq_enable(ir, MTK_IRINT_EN);
|
||
|
+
|
||
|
+ dev_info(dev, "Initialized MT7623 IR driver, sample period = %luus\n",
|
||
|
+ DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, 1000));
|
||
|
+
|
||
|
+ return 0;
|
||
|
+
|
||
|
+exit_clkdisable_clk:
|
||
|
+ clk_disable_unprepare(ir->clk);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+static int mtk_ir_remove(struct platform_device *pdev)
|
||
|
+{
|
||
|
+ struct mtk_ir *ir = platform_get_drvdata(pdev);
|
||
|
+
|
||
|
+ /* Avoid contention between remove handler and
|
||
|
+ * IRQ handler so that disabling IR interrupt and
|
||
|
+ * waiting for pending IRQ handler to complete
|
||
|
+ */
|
||
|
+ mtk_irq_disable(ir, MTK_IRINT_EN);
|
||
|
+ synchronize_irq(ir->irq);
|
||
|
+
|
||
|
+ clk_disable_unprepare(ir->clk);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static const struct of_device_id mtk_ir_match[] = {
|
||
|
+ { .compatible = "mediatek,mt7623-cir" },
|
||
|
+ {},
|
||
|
+};
|
||
|
+MODULE_DEVICE_TABLE(of, mtk_ir_match);
|
||
|
+
|
||
|
+static struct platform_driver mtk_ir_driver = {
|
||
|
+ .probe = mtk_ir_probe,
|
||
|
+ .remove = mtk_ir_remove,
|
||
|
+ .driver = {
|
||
|
+ .name = MTK_IR_DEV,
|
||
|
+ .of_match_table = mtk_ir_match,
|
||
|
+ },
|
||
|
+};
|
||
|
+
|
||
|
+module_platform_driver(mtk_ir_driver);
|
||
|
+
|
||
|
+MODULE_DESCRIPTION("Mediatek IR Receiver Controller Driver");
|
||
|
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
|
||
|
+MODULE_LICENSE("GPL");
|
||
|
--- a/drivers/media/rc/Makefile
|
||
|
+++ b/drivers/media/rc/Makefile
|
||
|
@@ -37,3 +37,4 @@ obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
|
||
|
obj-$(CONFIG_RC_ST) += st_rc.o
|
||
|
obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
|
||
|
obj-$(CONFIG_IR_IMG) += img-ir/
|
||
|
+obj-$(CONFIG_IR_MTK) += mtk-cir.o
|
||
|
--- a/drivers/media/rc/rc-main.c
|
||
|
+++ b/drivers/media/rc/rc-main.c
|
||
|
@@ -1355,7 +1355,7 @@ static struct device_type rc_dev_type =
|
||
|
.uevent = rc_dev_uevent,
|
||
|
};
|
||
|
|
||
|
-struct rc_dev *rc_allocate_device(void)
|
||
|
+struct rc_dev *rc_allocate_device(enum rc_driver_type type)
|
||
|
{
|
||
|
struct rc_dev *dev;
|
||
|
|
||
|
@@ -1382,6 +1382,8 @@ struct rc_dev *rc_allocate_device(void)
|
||
|
dev->dev.class = &rc_class;
|
||
|
device_initialize(&dev->dev);
|
||
|
|
||
|
+ dev->driver_type = type;
|
||
|
+
|
||
|
__module_get(THIS_MODULE);
|
||
|
return dev;
|
||
|
}
|
||
|
@@ -1403,6 +1405,35 @@ void rc_free_device(struct rc_dev *dev)
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(rc_free_device);
|
||
|
|
||
|
+static void devm_rc_alloc_release(struct device *dev, void *res)
|
||
|
+{
|
||
|
+ rc_free_device(*(struct rc_dev **)res);
|
||
|
+}
|
||
|
+
|
||
|
+struct rc_dev *devm_rc_allocate_device(struct device *dev,
|
||
|
+ enum rc_driver_type type)
|
||
|
+{
|
||
|
+ struct rc_dev **dr, *rc;
|
||
|
+
|
||
|
+ dr = devres_alloc(devm_rc_alloc_release, sizeof(*dr), GFP_KERNEL);
|
||
|
+ if (!dr)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ rc = rc_allocate_device(type);
|
||
|
+ if (!rc) {
|
||
|
+ devres_free(dr);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ rc->dev.parent = dev;
|
||
|
+ rc->managed_alloc = true;
|
||
|
+ *dr = rc;
|
||
|
+ devres_add(dev, dr);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+EXPORT_SYMBOL_GPL(devm_rc_allocate_device);
|
||
|
+
|
||
|
int rc_register_device(struct rc_dev *dev)
|
||
|
{
|
||
|
static bool raw_init = false; /* raw decoders loaded? */
|
||
|
@@ -1536,6 +1567,33 @@ out_unlock:
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(rc_register_device);
|
||
|
|
||
|
+static void devm_rc_release(struct device *dev, void *res)
|
||
|
+{
|
||
|
+ rc_unregister_device(*(struct rc_dev **)res);
|
||
|
+}
|
||
|
+
|
||
|
+int devm_rc_register_device(struct device *parent, struct rc_dev *dev)
|
||
|
+{
|
||
|
+ struct rc_dev **dr;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ dr = devres_alloc(devm_rc_release, sizeof(*dr), GFP_KERNEL);
|
||
|
+ if (!dr)
|
||
|
+ return -ENOMEM;
|
||
|
+
|
||
|
+ ret = rc_register_device(dev);
|
||
|
+ if (ret) {
|
||
|
+ devres_free(dr);
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
+
|
||
|
+ *dr = dev;
|
||
|
+ devres_add(parent, dr);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+EXPORT_SYMBOL_GPL(devm_rc_register_device);
|
||
|
+
|
||
|
void rc_unregister_device(struct rc_dev *dev)
|
||
|
{
|
||
|
if (!dev)
|
||
|
@@ -1557,7 +1615,8 @@ void rc_unregister_device(struct rc_dev
|
||
|
|
||
|
ida_simple_remove(&rc_ida, dev->minor);
|
||
|
|
||
|
- rc_free_device(dev);
|
||
|
+ if (!dev->managed_alloc)
|
||
|
+ rc_free_device(dev);
|
||
|
}
|
||
|
|
||
|
EXPORT_SYMBOL_GPL(rc_unregister_device);
|
||
|
--- a/include/media/rc-core.h
|
||
|
+++ b/include/media/rc-core.h
|
||
|
@@ -68,6 +68,7 @@ enum rc_filter_type {
|
||
|
* struct rc_dev - represents a remote control device
|
||
|
* @dev: driver model's view of this device
|
||
|
* @initialized: 1 if the device init has completed, 0 otherwise
|
||
|
+ * @managed_alloc: devm_rc_allocate_device was used to create rc_dev
|
||
|
* @sysfs_groups: sysfs attribute groups
|
||
|
* @input_name: name of the input child device
|
||
|
* @input_phys: physical path to the input child device
|
||
|
@@ -131,6 +132,7 @@ enum rc_filter_type {
|
||
|
struct rc_dev {
|
||
|
struct device dev;
|
||
|
atomic_t initialized;
|
||
|
+ bool managed_alloc;
|
||
|
const struct attribute_group *sysfs_groups[5];
|
||
|
const char *input_name;
|
||
|
const char *input_phys;
|
||
|
@@ -198,9 +200,19 @@ struct rc_dev {
|
||
|
/**
|
||
|
* rc_allocate_device - Allocates a RC device
|
||
|
*
|
||
|
+ * @rc_driver_type: specifies the type of the RC output to be allocated
|
||
|
* returns a pointer to struct rc_dev.
|
||
|
*/
|
||
|
-struct rc_dev *rc_allocate_device(void);
|
||
|
+struct rc_dev *rc_allocate_device(enum rc_driver_type);
|
||
|
+
|
||
|
+/**
|
||
|
+ * devm_rc_allocate_device - Managed RC device allocation
|
||
|
+ *
|
||
|
+ * @dev: pointer to struct device
|
||
|
+ * @rc_driver_type: specifies the type of the RC output to be allocated
|
||
|
+ * returns a pointer to struct rc_dev.
|
||
|
+ */
|
||
|
+struct rc_dev *devm_rc_allocate_device(struct device *dev, enum rc_driver_type);
|
||
|
|
||
|
/**
|
||
|
* rc_free_device - Frees a RC device
|
||
|
@@ -217,6 +229,14 @@ void rc_free_device(struct rc_dev *dev);
|
||
|
int rc_register_device(struct rc_dev *dev);
|
||
|
|
||
|
/**
|
||
|
+ * devm_rc_register_device - Manageded registering of a RC device
|
||
|
+ *
|
||
|
+ * @parent: pointer to struct device.
|
||
|
+ * @dev: pointer to struct rc_dev.
|
||
|
+ */
|
||
|
+int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
|
||
|
+
|
||
|
+/**
|
||
|
* rc_unregister_device - Unregisters a RC device
|
||
|
*
|
||
|
* @dev: pointer to struct rc_dev.
|
||
|
--- a/drivers/media/common/siano/smsir.c
|
||
|
+++ b/drivers/media/common/siano/smsir.c
|
||
|
@@ -58,7 +58,7 @@ int sms_ir_init(struct smscore_device_t
|
||
|
struct rc_dev *dev;
|
||
|
|
||
|
pr_debug("Allocating rc device\n");
|
||
|
- dev = rc_allocate_device();
|
||
|
+ dev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!dev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
--- a/drivers/media/i2c/ir-kbd-i2c.c
|
||
|
+++ b/drivers/media/i2c/ir-kbd-i2c.c
|
||
|
@@ -428,7 +428,7 @@ static int ir_probe(struct i2c_client *c
|
||
|
* If platform_data doesn't specify rc_dev, initialize it
|
||
|
* internally
|
||
|
*/
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!rc)
|
||
|
return -ENOMEM;
|
||
|
}
|
||
|
--- a/drivers/media/pci/bt8xx/bttv-input.c
|
||
|
+++ b/drivers/media/pci/bt8xx/bttv-input.c
|
||
|
@@ -424,7 +424,7 @@ int bttv_input_init(struct bttv *btv)
|
||
|
return -ENODEV;
|
||
|
|
||
|
ir = kzalloc(sizeof(*ir),GFP_KERNEL);
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!ir || !rc)
|
||
|
goto err_out_free;
|
||
|
|
||
|
--- a/drivers/media/pci/cx23885/cx23885-input.c
|
||
|
+++ b/drivers/media/pci/cx23885/cx23885-input.c
|
||
|
@@ -267,7 +267,6 @@ int cx23885_input_init(struct cx23885_de
|
||
|
struct cx23885_kernel_ir *kernel_ir;
|
||
|
struct rc_dev *rc;
|
||
|
char *rc_map;
|
||
|
- enum rc_driver_type driver_type;
|
||
|
u64 allowed_protos;
|
||
|
|
||
|
int ret;
|
||
|
@@ -352,7 +351,7 @@ int cx23885_input_init(struct cx23885_de
|
||
|
pci_name(dev->pci));
|
||
|
|
||
|
/* input device */
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rc) {
|
||
|
ret = -ENOMEM;
|
||
|
goto err_out_free;
|
||
|
@@ -371,7 +370,6 @@ int cx23885_input_init(struct cx23885_de
|
||
|
rc->input_id.product = dev->pci->device;
|
||
|
}
|
||
|
rc->dev.parent = &dev->pci->dev;
|
||
|
- rc->driver_type = driver_type;
|
||
|
rc->allowed_protocols = allowed_protos;
|
||
|
rc->priv = kernel_ir;
|
||
|
rc->open = cx23885_input_ir_open;
|
||
|
--- a/drivers/media/pci/cx88/cx88-input.c
|
||
|
+++ b/drivers/media/pci/cx88/cx88-input.c
|
||
|
@@ -272,7 +272,7 @@ int cx88_ir_init(struct cx88_core *core,
|
||
|
*/
|
||
|
|
||
|
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
|
||
|
- dev = rc_allocate_device();
|
||
|
+ dev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!ir || !dev)
|
||
|
goto err_out_free;
|
||
|
|
||
|
@@ -482,7 +482,6 @@ int cx88_ir_init(struct cx88_core *core,
|
||
|
dev->scancode_mask = hardware_mask;
|
||
|
|
||
|
if (ir->sampling) {
|
||
|
- dev->driver_type = RC_DRIVER_IR_RAW;
|
||
|
dev->timeout = 10 * 1000 * 1000; /* 10 ms */
|
||
|
} else {
|
||
|
dev->driver_type = RC_DRIVER_SCANCODE;
|
||
|
--- a/drivers/media/pci/dm1105/dm1105.c
|
||
|
+++ b/drivers/media/pci/dm1105/dm1105.c
|
||
|
@@ -744,7 +744,7 @@ static int dm1105_ir_init(struct dm1105_
|
||
|
struct rc_dev *dev;
|
||
|
int err = -ENOMEM;
|
||
|
|
||
|
- dev = rc_allocate_device();
|
||
|
+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!dev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
@@ -753,7 +753,6 @@ static int dm1105_ir_init(struct dm1105_
|
||
|
|
||
|
dev->driver_name = MODULE_NAME;
|
||
|
dev->map_name = RC_MAP_DM1105_NEC;
|
||
|
- dev->driver_type = RC_DRIVER_SCANCODE;
|
||
|
dev->input_name = "DVB on-card IR receiver";
|
||
|
dev->input_phys = dm1105->ir.input_phys;
|
||
|
dev->input_id.bustype = BUS_PCI;
|
||
|
--- a/drivers/media/pci/mantis/mantis_input.c
|
||
|
+++ b/drivers/media/pci/mantis/mantis_input.c
|
||
|
@@ -39,7 +39,7 @@ int mantis_input_init(struct mantis_pci
|
||
|
struct rc_dev *dev;
|
||
|
int err;
|
||
|
|
||
|
- dev = rc_allocate_device();
|
||
|
+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!dev) {
|
||
|
dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
|
||
|
err = -ENOMEM;
|
||
|
--- a/drivers/media/pci/saa7134/saa7134-input.c
|
||
|
+++ b/drivers/media/pci/saa7134/saa7134-input.c
|
||
|
@@ -849,7 +849,7 @@ int saa7134_input_init1(struct saa7134_d
|
||
|
}
|
||
|
|
||
|
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!ir || !rc) {
|
||
|
err = -ENOMEM;
|
||
|
goto err_out_free;
|
||
|
--- a/drivers/media/pci/smipcie/smipcie-ir.c
|
||
|
+++ b/drivers/media/pci/smipcie/smipcie-ir.c
|
||
|
@@ -183,7 +183,7 @@ int smi_ir_init(struct smi_dev *dev)
|
||
|
struct rc_dev *rc_dev;
|
||
|
struct smi_rc *ir = &dev->ir;
|
||
|
|
||
|
- rc_dev = rc_allocate_device();
|
||
|
+ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!rc_dev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
@@ -202,7 +202,6 @@ int smi_ir_init(struct smi_dev *dev)
|
||
|
rc_dev->input_id.product = dev->pci_dev->subsystem_device;
|
||
|
rc_dev->dev.parent = &dev->pci_dev->dev;
|
||
|
|
||
|
- rc_dev->driver_type = RC_DRIVER_SCANCODE;
|
||
|
rc_dev->map_name = dev->info->rc_map;
|
||
|
|
||
|
ir->rc_dev = rc_dev;
|
||
|
--- a/drivers/media/pci/ttpci/budget-ci.c
|
||
|
+++ b/drivers/media/pci/ttpci/budget-ci.c
|
||
|
@@ -177,7 +177,7 @@ static int msp430_ir_init(struct budget_
|
||
|
struct rc_dev *dev;
|
||
|
int error;
|
||
|
|
||
|
- dev = rc_allocate_device();
|
||
|
+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!dev) {
|
||
|
printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
|
||
|
return -ENOMEM;
|
||
|
--- a/drivers/media/rc/ati_remote.c
|
||
|
+++ b/drivers/media/rc/ati_remote.c
|
||
|
@@ -765,7 +765,6 @@ static void ati_remote_rc_init(struct at
|
||
|
struct rc_dev *rdev = ati_remote->rdev;
|
||
|
|
||
|
rdev->priv = ati_remote;
|
||
|
- rdev->driver_type = RC_DRIVER_SCANCODE;
|
||
|
rdev->allowed_protocols = RC_BIT_OTHER;
|
||
|
rdev->driver_name = "ati_remote";
|
||
|
|
||
|
@@ -852,7 +851,7 @@ static int ati_remote_probe(struct usb_i
|
||
|
}
|
||
|
|
||
|
ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
|
||
|
- rc_dev = rc_allocate_device();
|
||
|
+ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!ati_remote || !rc_dev)
|
||
|
goto exit_free_dev_rdev;
|
||
|
|
||
|
--- a/drivers/media/rc/ene_ir.c
|
||
|
+++ b/drivers/media/rc/ene_ir.c
|
||
|
@@ -1012,7 +1012,7 @@ static int ene_probe(struct pnp_dev *pnp
|
||
|
|
||
|
/* allocate memory */
|
||
|
dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
|
||
|
- rdev = rc_allocate_device();
|
||
|
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!dev || !rdev)
|
||
|
goto exit_free_dev_rdev;
|
||
|
|
||
|
--- a/drivers/media/rc/fintek-cir.c
|
||
|
+++ b/drivers/media/rc/fintek-cir.c
|
||
|
@@ -496,7 +496,7 @@ static int fintek_probe(struct pnp_dev *
|
||
|
return ret;
|
||
|
|
||
|
/* input device for IR remote (and tx) */
|
||
|
- rdev = rc_allocate_device();
|
||
|
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rdev)
|
||
|
goto exit_free_dev_rdev;
|
||
|
|
||
|
--- a/drivers/media/rc/gpio-ir-recv.c
|
||
|
+++ b/drivers/media/rc/gpio-ir-recv.c
|
||
|
@@ -143,14 +143,13 @@ static int gpio_ir_recv_probe(struct pla
|
||
|
if (!gpio_dev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
- rcdev = rc_allocate_device();
|
||
|
+ rcdev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rcdev) {
|
||
|
rc = -ENOMEM;
|
||
|
goto err_allocate_device;
|
||
|
}
|
||
|
|
||
|
rcdev->priv = gpio_dev;
|
||
|
- rcdev->driver_type = RC_DRIVER_IR_RAW;
|
||
|
rcdev->input_name = GPIO_IR_DEVICE_NAME;
|
||
|
rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
|
||
|
rcdev->input_id.bustype = BUS_HOST;
|
||
|
--- a/drivers/media/rc/igorplugusb.c
|
||
|
+++ b/drivers/media/rc/igorplugusb.c
|
||
|
@@ -190,7 +190,7 @@ static int igorplugusb_probe(struct usb_
|
||
|
|
||
|
usb_make_path(udev, ir->phys, sizeof(ir->phys));
|
||
|
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rc)
|
||
|
goto fail;
|
||
|
|
||
|
@@ -198,7 +198,6 @@ static int igorplugusb_probe(struct usb_
|
||
|
rc->input_phys = ir->phys;
|
||
|
usb_to_input_id(udev, &rc->input_id);
|
||
|
rc->dev.parent = &intf->dev;
|
||
|
- rc->driver_type = RC_DRIVER_IR_RAW;
|
||
|
/*
|
||
|
* This device can only store 36 pulses + spaces, which is not enough
|
||
|
* for the NEC protocol and many others.
|
||
|
--- a/drivers/media/rc/iguanair.c
|
||
|
+++ b/drivers/media/rc/iguanair.c
|
||
|
@@ -431,7 +431,7 @@ static int iguanair_probe(struct usb_int
|
||
|
struct usb_host_interface *idesc;
|
||
|
|
||
|
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!ir || !rc) {
|
||
|
ret = -ENOMEM;
|
||
|
goto out;
|
||
|
--- a/drivers/media/rc/img-ir/img-ir-hw.c
|
||
|
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
|
||
|
@@ -1071,7 +1071,7 @@ int img_ir_probe_hw(struct img_ir_priv *
|
||
|
}
|
||
|
|
||
|
/* Allocate hardware decoder */
|
||
|
- hw->rdev = rdev = rc_allocate_device();
|
||
|
+ hw->rdev = rdev = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!rdev) {
|
||
|
dev_err(priv->dev, "cannot allocate input device\n");
|
||
|
error = -ENOMEM;
|
||
|
--- a/drivers/media/rc/img-ir/img-ir-raw.c
|
||
|
+++ b/drivers/media/rc/img-ir/img-ir-raw.c
|
||
|
@@ -110,7 +110,7 @@ int img_ir_probe_raw(struct img_ir_priv
|
||
|
setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv);
|
||
|
|
||
|
/* Allocate raw decoder */
|
||
|
- raw->rdev = rdev = rc_allocate_device();
|
||
|
+ raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rdev) {
|
||
|
dev_err(priv->dev, "cannot allocate raw input device\n");
|
||
|
return -ENOMEM;
|
||
|
@@ -118,7 +118,6 @@ int img_ir_probe_raw(struct img_ir_priv
|
||
|
rdev->priv = priv;
|
||
|
rdev->map_name = RC_MAP_EMPTY;
|
||
|
rdev->input_name = "IMG Infrared Decoder Raw";
|
||
|
- rdev->driver_type = RC_DRIVER_IR_RAW;
|
||
|
|
||
|
/* Register raw decoder */
|
||
|
error = rc_register_device(rdev);
|
||
|
--- a/drivers/media/rc/imon.c
|
||
|
+++ b/drivers/media/rc/imon.c
|
||
|
@@ -1951,7 +1951,7 @@ static struct rc_dev *imon_init_rdev(str
|
||
|
const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x88 };
|
||
|
|
||
|
- rdev = rc_allocate_device();
|
||
|
+ rdev = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!rdev) {
|
||
|
dev_err(ictx->dev, "remote control dev allocation failed\n");
|
||
|
goto out;
|
||
|
@@ -1969,7 +1969,6 @@ static struct rc_dev *imon_init_rdev(str
|
||
|
rdev->dev.parent = ictx->dev;
|
||
|
|
||
|
rdev->priv = ictx;
|
||
|
- rdev->driver_type = RC_DRIVER_SCANCODE;
|
||
|
rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
|
||
|
rdev->change_protocol = imon_ir_change_protocol;
|
||
|
rdev->driver_name = MOD_NAME;
|
||
|
--- a/drivers/media/rc/ir-hix5hd2.c
|
||
|
+++ b/drivers/media/rc/ir-hix5hd2.c
|
||
|
@@ -222,7 +222,7 @@ static int hix5hd2_ir_probe(struct platf
|
||
|
return priv->irq;
|
||
|
}
|
||
|
|
||
|
- rdev = rc_allocate_device();
|
||
|
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rdev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
--- a/drivers/media/rc/ite-cir.c
|
||
|
+++ b/drivers/media/rc/ite-cir.c
|
||
|
@@ -1472,7 +1472,7 @@ static int ite_probe(struct pnp_dev *pde
|
||
|
return ret;
|
||
|
|
||
|
/* input device for IR remote (and tx) */
|
||
|
- rdev = rc_allocate_device();
|
||
|
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rdev)
|
||
|
goto exit_free_dev_rdev;
|
||
|
itdev->rdev = rdev;
|
||
|
--- a/drivers/media/rc/mceusb.c
|
||
|
+++ b/drivers/media/rc/mceusb.c
|
||
|
@@ -1220,7 +1220,7 @@ static struct rc_dev *mceusb_init_rc_dev
|
||
|
struct rc_dev *rc;
|
||
|
int ret;
|
||
|
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rc) {
|
||
|
dev_err(dev, "remote dev allocation failed");
|
||
|
goto out;
|
||
|
--- a/drivers/media/rc/meson-ir.c
|
||
|
+++ b/drivers/media/rc/meson-ir.c
|
||
|
@@ -131,7 +131,7 @@ static int meson_ir_probe(struct platfor
|
||
|
return ir->irq;
|
||
|
}
|
||
|
|
||
|
- ir->rc = rc_allocate_device();
|
||
|
+ ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!ir->rc) {
|
||
|
dev_err(dev, "failed to allocate rc device\n");
|
||
|
return -ENOMEM;
|
||
|
--- a/drivers/media/rc/rc-loopback.c
|
||
|
+++ b/drivers/media/rc/rc-loopback.c
|
||
|
@@ -181,7 +181,7 @@ static int __init loop_init(void)
|
||
|
struct rc_dev *rc;
|
||
|
int ret;
|
||
|
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rc) {
|
||
|
printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
|
||
|
return -ENOMEM;
|
||
|
--- a/drivers/media/rc/st_rc.c
|
||
|
+++ b/drivers/media/rc/st_rc.c
|
||
|
@@ -235,7 +235,7 @@ static int st_rc_probe(struct platform_d
|
||
|
if (!rc_dev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
- rdev = rc_allocate_device();
|
||
|
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
|
||
|
if (!rdev)
|
||
|
return -ENOMEM;
|
||
|
--- a/drivers/media/rc/streamzap.c
|
||
|
+++ b/drivers/media/rc/streamzap.c
|
||
|
@@ -291,7 +291,7 @@ static struct rc_dev *streamzap_init_rc_
|
||
|
struct device *dev = sz->dev;
|
||
|
int ret;
|
||
|
|
||
|
- rdev = rc_allocate_device();
|
||
|
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!rdev) {
|
||
|
dev_err(dev, "remote dev allocation failed\n");
|
||
|
goto out;
|
||
|
--- a/drivers/media/rc/sunxi-cir.c
|
||
|
+++ b/drivers/media/rc/sunxi-cir.c
|
||
|
@@ -212,7 +212,7 @@ static int sunxi_ir_probe(struct platfor
|
||
|
goto exit_clkdisable_clk;
|
||
|
}
|
||
|
|
||
|
- ir->rc = rc_allocate_device();
|
||
|
+ ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!ir->rc) {
|
||
|
dev_err(dev, "failed to allocate device\n");
|
||
|
ret = -ENOMEM;
|
||
|
--- a/drivers/media/rc/ttusbir.c
|
||
|
+++ b/drivers/media/rc/ttusbir.c
|
||
|
@@ -205,7 +205,7 @@ static int ttusbir_probe(struct usb_inte
|
||
|
int altsetting = -1;
|
||
|
|
||
|
tt = kzalloc(sizeof(*tt), GFP_KERNEL);
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!tt || !rc) {
|
||
|
ret = -ENOMEM;
|
||
|
goto out;
|
||
|
--- a/drivers/media/rc/winbond-cir.c
|
||
|
+++ b/drivers/media/rc/winbond-cir.c
|
||
|
@@ -1062,13 +1062,12 @@ wbcir_probe(struct pnp_dev *device, cons
|
||
|
if (err)
|
||
|
goto exit_free_data;
|
||
|
|
||
|
- data->dev = rc_allocate_device();
|
||
|
+ data->dev = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!data->dev) {
|
||
|
err = -ENOMEM;
|
||
|
goto exit_unregister_led;
|
||
|
}
|
||
|
|
||
|
- data->dev->driver_type = RC_DRIVER_IR_RAW;
|
||
|
data->dev->driver_name = DRVNAME;
|
||
|
data->dev->input_name = WBCIR_NAME;
|
||
|
data->dev->input_phys = "wbcir/cir0";
|
||
|
--- a/drivers/media/usb/au0828/au0828-input.c
|
||
|
+++ b/drivers/media/usb/au0828/au0828-input.c
|
||
|
@@ -298,7 +298,7 @@ int au0828_rc_register(struct au0828_dev
|
||
|
return -ENODEV;
|
||
|
|
||
|
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||
|
if (!ir || !rc)
|
||
|
goto error;
|
||
|
|
||
|
@@ -343,7 +343,6 @@ int au0828_rc_register(struct au0828_dev
|
||
|
rc->input_id.product = le16_to_cpu(dev->usbdev->descriptor.idProduct);
|
||
|
rc->dev.parent = &dev->usbdev->dev;
|
||
|
rc->driver_name = "au0828-input";
|
||
|
- rc->driver_type = RC_DRIVER_IR_RAW;
|
||
|
rc->allowed_protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 |
|
||
|
RC_BIT_RC5;
|
||
|
|
||
|
--- a/drivers/media/usb/cx231xx/cx231xx-input.c
|
||
|
+++ b/drivers/media/usb/cx231xx/cx231xx-input.c
|
||
|
@@ -72,7 +72,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
|
||
|
|
||
|
memset(&info, 0, sizeof(struct i2c_board_info));
|
||
|
memset(&dev->init_data, 0, sizeof(dev->init_data));
|
||
|
- dev->init_data.rc_dev = rc_allocate_device();
|
||
|
+ dev->init_data.rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!dev->init_data.rc_dev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
|
||
|
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
|
||
|
@@ -147,7 +147,7 @@ static int dvb_usbv2_remote_init(struct
|
||
|
if (!d->rc.map_name)
|
||
|
return 0;
|
||
|
|
||
|
- dev = rc_allocate_device();
|
||
|
+ dev = rc_allocate_device(d->rc.driver_type);
|
||
|
if (!dev) {
|
||
|
ret = -ENOMEM;
|
||
|
goto err;
|
||
|
@@ -162,7 +162,6 @@ static int dvb_usbv2_remote_init(struct
|
||
|
/* TODO: likely RC-core should took const char * */
|
||
|
dev->driver_name = (char *) d->props->driver_name;
|
||
|
dev->map_name = d->rc.map_name;
|
||
|
- dev->driver_type = d->rc.driver_type;
|
||
|
dev->allowed_protocols = d->rc.allowed_protos;
|
||
|
dev->change_protocol = d->rc.change_protocol;
|
||
|
dev->priv = d;
|
||
|
--- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c
|
||
|
+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
|
||
|
@@ -265,7 +265,7 @@ static int rc_core_dvb_usb_remote_init(s
|
||
|
int err, rc_interval;
|
||
|
struct rc_dev *dev;
|
||
|
|
||
|
- dev = rc_allocate_device();
|
||
|
+ dev = rc_allocate_device(d->props.rc.core.driver_type);
|
||
|
if (!dev)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
@@ -273,7 +273,6 @@ static int rc_core_dvb_usb_remote_init(s
|
||
|
dev->map_name = d->props.rc.core.rc_codes;
|
||
|
dev->change_protocol = d->props.rc.core.change_protocol;
|
||
|
dev->allowed_protocols = d->props.rc.core.allowed_protos;
|
||
|
- dev->driver_type = d->props.rc.core.driver_type;
|
||
|
usb_to_input_id(d->udev, &dev->input_id);
|
||
|
dev->input_name = "IR-receiver inside an USB DVB receiver";
|
||
|
dev->input_phys = d->rc_phys;
|
||
|
--- a/drivers/media/usb/em28xx/em28xx-input.c
|
||
|
+++ b/drivers/media/usb/em28xx/em28xx-input.c
|
||
|
@@ -713,7 +713,7 @@ static int em28xx_ir_init(struct em28xx
|
||
|
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
|
||
|
if (!ir)
|
||
|
return -ENOMEM;
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!rc)
|
||
|
goto error;
|
||
|
|
||
|
--- a/drivers/media/usb/tm6000/tm6000-input.c
|
||
|
+++ b/drivers/media/usb/tm6000/tm6000-input.c
|
||
|
@@ -429,7 +429,7 @@ int tm6000_ir_init(struct tm6000_core *d
|
||
|
return 0;
|
||
|
|
||
|
ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
|
||
|
- rc = rc_allocate_device();
|
||
|
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
|
||
|
if (!ir || !rc)
|
||
|
goto out;
|
||
|
|
||
|
@@ -456,7 +456,6 @@ int tm6000_ir_init(struct tm6000_core *d
|
||
|
ir->polling = 50;
|
||
|
INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
|
||
|
}
|
||
|
- rc->driver_type = RC_DRIVER_SCANCODE;
|
||
|
|
||
|
snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
|
||
|
dev->name);
|