Make drivers/media/rc/rc-ir-raw.c a separate kernel module. Drivers which use IR decoding must use these functions: rc_register_ir_raw_device() rc_unregister_ir_raw_device() instead of: rc_register_device() rc_unregister_device() This allows scancode drivers to skip lots of unnecessary functionality. Signed-off-by: David Härdeman <david@xxxxxxxxxxx> --- drivers/media/common/siano/smsir.c | 5 +- drivers/media/common/siano/smsir.h | 2 - drivers/media/i2c/cx25840/cx25840-ir.c | 2 - drivers/media/pci/cx23885/cx23885-input.c | 13 +--- drivers/media/pci/cx23885/cx23888-ir.c | 2 - drivers/media/pci/cx88/cx88-input.c | 18 +++--- drivers/media/pci/dm1105/dm1105.c | 1 drivers/media/pci/saa7134/saa7134-input.c | 14 +++-- drivers/media/pci/saa7134/saa7134.h | 2 - drivers/media/rc/Makefile | 3 + drivers/media/rc/ati_remote.c | 1 drivers/media/rc/ene_ir.c | 9 +-- drivers/media/rc/fintek-cir.c | 7 +- drivers/media/rc/gpio-ir-recv.c | 9 +-- drivers/media/rc/iguanair.c | 7 +- drivers/media/rc/img-ir/img-ir-raw.c | 7 +- drivers/media/rc/imon.c | 1 drivers/media/rc/ite-cir.c | 9 +-- drivers/media/rc/mceusb.c | 7 +- drivers/media/rc/nuvoton-cir.c | 7 +- drivers/media/rc/rc-core-priv.h | 10 ++- drivers/media/rc/rc-ir-raw.c | 39 +++++++++---- drivers/media/rc/rc-loopback.c | 7 +- drivers/media/rc/rc-main.c | 36 +----------- drivers/media/rc/redrat3.c | 7 +- drivers/media/rc/streamzap.c | 7 +- drivers/media/rc/ttusbir.c | 9 +-- drivers/media/rc/winbond-cir.c | 9 +-- drivers/media/usb/dvb-usb-v2/dvb_usb.h | 5 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 12 +++- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 2 - drivers/media/usb/dvb-usb/dvb-usb-remote.c | 9 ++- drivers/media/usb/dvb-usb/dvb-usb.h | 5 +- drivers/media/usb/dvb-usb/technisat-usb2.c | 2 - drivers/media/usb/em28xx/em28xx-input.c | 5 -- drivers/media/usb/tm6000/tm6000-input.c | 1 include/media/rc-core.h | 73 +----------------------- include/media/rc-ir-raw.h | 83 +++++++++++++++++++++++++++ 38 files changed, 222 insertions(+), 225 deletions(-) create mode 100644 include/media/rc-ir-raw.h diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 273043e..f6938f4 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -87,14 +87,13 @@ int sms_ir_init(struct smscore_device_t *coredev) #endif dev->priv = coredev; - dev->driver_type = RC_DRIVER_IR_RAW; dev->allowed_protocols = RC_BIT_ALL; dev->map_name = sms_get_board(board_id)->rc_codes; dev->driver_name = MODULE_NAME; sms_log("Input device (IR) %s is set for key events", dev->input_name); - err = rc_register_device(dev); + err = rc_register_ir_raw_device(dev); if (err < 0) { sms_err("Failed to register device"); rc_free_device(dev); @@ -108,7 +107,7 @@ int sms_ir_init(struct smscore_device_t *coredev) void sms_ir_exit(struct smscore_device_t *coredev) { if (coredev->ir.dev) - rc_unregister_device(coredev->ir.dev); + rc_unregister_ir_raw_device(coredev->ir.dev); sms_log(""); } diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h index fc8b792..05a2b01 100644 --- a/drivers/media/common/siano/smsir.h +++ b/drivers/media/common/siano/smsir.h @@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define __SMS_IR_H__ #include <linux/input.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #define IR_DEFAULT_TIMEOUT 100 diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c index e6588ee..119d4e8 100644 --- a/drivers/media/i2c/cx25840/cx25840-ir.c +++ b/drivers/media/i2c/cx25840/cx25840-ir.c @@ -25,7 +25,7 @@ #include <linux/kfifo.h> #include <linux/module.h> #include <media/cx25840.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include "cx25840-core.h" diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 1940c18..e2ba28d 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -36,7 +36,7 @@ */ #include <linux/slab.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include <media/v4l2-subdev.h> #include "cx23885.h" @@ -258,7 +258,6 @@ int cx23885_input_init(struct cx23885_dev *dev) struct cx23885_kernel_ir *kernel_ir; struct rc_dev *rc; char *rc_map; - enum rc_driver_type driver_type; unsigned long allowed_protos; int ret; @@ -276,28 +275,24 @@ int cx23885_input_init(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_HAUPPAUGE_HVR1250: /* Integrated CX2388[58] IR controller */ - driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_ALL; /* The grey Hauppauge RC-5 remote */ rc_map = RC_MAP_HAUPPAUGE; break; case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: /* Integrated CX23885 IR controller */ - driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_NEC; /* The grey Terratec remote with orange buttons */ rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS; break; case CX23885_BOARD_TEVII_S470: /* Integrated CX23885 IR controller */ - driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_ALL; /* A guess at the remote */ rc_map = RC_MAP_TEVII_NEC; break; case CX23885_BOARD_MYGICA_X8507: /* Integrated CX23885 IR controller */ - driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_ALL; /* A guess at the remote */ rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02; @@ -305,7 +300,6 @@ int cx23885_input_init(struct cx23885_dev *dev) case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: /* Integrated CX23885 IR controller */ - driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_ALL; /* A guess at the remote */ rc_map = RC_MAP_TBS_NEC; @@ -345,7 +339,6 @@ int cx23885_input_init(struct cx23885_dev *dev) 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; @@ -355,7 +348,7 @@ int cx23885_input_init(struct cx23885_dev *dev) /* Go */ dev->kernel_ir = kernel_ir; - ret = rc_register_device(rc); + ret = rc_register_ir_raw_device(rc); if (ret) goto err_out_stop; @@ -379,7 +372,7 @@ void cx23885_input_fini(struct cx23885_dev *dev) if (dev->kernel_ir == NULL) return; - rc_unregister_device(dev->kernel_ir->rc); + rc_unregister_ir_raw_device(dev->kernel_ir->rc); kfree(dev->kernel_ir->phys); kfree(dev->kernel_ir->name); kfree(dev->kernel_ir); diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index 2c951de..c4961f8 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -25,7 +25,7 @@ #include <linux/slab.h> #include <media/v4l2-device.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include "cx23885.h" #include "cx23888-ir.h" diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index cb587ce..2b68ede 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -29,7 +29,7 @@ #include <linux/module.h> #include "cx88.h" -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #define MODULE_NAME "cx88xx" @@ -474,20 +474,17 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) dev->open = cx88_ir_open; dev->close = cx88_ir_close; dev->scancode_mask = hardware_mask; + ir->core = core; + core->ir = ir; if (ir->sampling) { - dev->driver_type = RC_DRIVER_IR_RAW; dev->timeout = 10 * 1000 * 1000; /* 10 ms */ + err = rc_register_ir_raw_device(dev); } else { - dev->driver_type = RC_DRIVER_SCANCODE; dev->allowed_protocols = rc_type; + err = rc_register_device(dev); } - ir->core = core; - core->ir = ir; - - /* all done */ - err = rc_register_device(dev); if (err) goto err_out_free; @@ -509,7 +506,10 @@ int cx88_ir_fini(struct cx88_core *core) return 0; cx88_ir_stop(core); - rc_unregister_device(ir->dev); + if (ir->sampling) + rc_unregister_ir_raw_device(ir->dev); + else + rc_unregister_device(ir->dev); kfree(ir); /* done */ diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index e8826c5..015aa07 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -752,7 +752,6 @@ static int dm1105_ir_init(struct dm1105_dev *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; diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 4ba61ff..27a3f48 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -864,9 +864,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) rc->priv = dev; rc->open = saa7134_ir_open; rc->close = saa7134_ir_close; - if (raw_decode) - rc->driver_type = RC_DRIVER_IR_RAW; - rc->input_name = ir->name; rc->input_phys = ir->phys; rc->input_id.bustype = BUS_PCI; @@ -882,7 +879,11 @@ int saa7134_input_init1(struct saa7134_dev *dev) rc->map_name = ir_codes; rc->driver_name = MODULE_NAME; - err = rc_register_device(rc); + if (raw_decode) + err = rc_register_ir_raw_device(rc); + else + err = rc_register_device(rc); + if (err) goto err_out_free; @@ -901,7 +902,10 @@ void saa7134_input_fini(struct saa7134_dev *dev) return; saa7134_ir_stop(dev); - rc_unregister_device(dev->remote->dev); + if (dev->remote->raw_decode) + rc_unregister_ir_raw_device(dev->remote->dev); + else + rc_unregister_device(dev->remote->dev); kfree(dev->remote); dev->remote = NULL; } diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 2474e84..5a25486 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -39,7 +39,7 @@ #include <media/v4l2-fh.h> #include <media/v4l2-ctrls.h> #include <media/tuner.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include <media/ir-kbd-i2c.h> #include <media/videobuf-dma-sg.h> #include <sound/core.h> diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 661f449..ac39628 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -1,8 +1,9 @@ -rc-core-objs := rc-main.o rc-keytable.o rc-ir-raw.o +rc-core-objs := rc-main.o rc-keytable.o obj-y += keymaps/ obj-$(CONFIG_RC_CORE) += rc-core.o +obj-$(CONFIG_RC_CORE) += rc-ir-raw.o obj-$(CONFIG_LIRC) += lirc_dev.o obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index 6ef5716..170aac8 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -784,7 +784,6 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote) 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"; diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index cab5da9..57d61e5 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -39,7 +39,7 @@ #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/slab.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include "ene_ir.h" static int sample_period; @@ -1053,7 +1053,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (!dev->hw_learning_and_tx_capable) learning_mode_force = false; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->priv = dev; rdev->open = ene_open; @@ -1083,7 +1082,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) device_set_wakeup_capable(&pnp_dev->dev, true); device_set_wakeup_enable(&pnp_dev->dev, true); - error = rc_register_device(rdev); + error = rc_register_ir_raw_device(rdev); if (error < 0) goto exit_free_dev_rdev; @@ -1104,7 +1103,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) exit_release_hw_io: release_region(dev->hw_io, ENE_IO_SIZE); exit_unregister_device: - rc_unregister_device(rdev); + rc_unregister_ir_raw_device(rdev); rdev = NULL; exit_free_dev_rdev: rc_free_device(rdev); @@ -1125,7 +1124,7 @@ static void ene_remove(struct pnp_dev *pnp_dev) free_irq(dev->irq, dev); release_region(dev->hw_io, ENE_IO_SIZE); - rc_unregister_device(dev->rdev); + rc_unregister_ir_raw_device(dev->rdev); kfree(dev); } diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index f000faf..ce2db15 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -32,7 +32,7 @@ #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/slab.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include <linux/pci_ids.h> #include "fintek-cir.h" @@ -540,7 +540,6 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id /* Set up the rc device */ rdev->priv = fintek; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = fintek_open; rdev->close = fintek_close; @@ -569,7 +568,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id FINTEK_DRIVER_NAME, (void *)fintek)) goto exit_free_cir_addr; - ret = rc_register_device(rdev); + ret = rc_register_ir_raw_device(rdev); if (ret) goto exit_free_irq; @@ -609,7 +608,7 @@ static void fintek_remove(struct pnp_dev *pdev) free_irq(fintek->cir_irq, fintek); release_region(fintek->cir_addr, fintek->cir_port_len); - rc_unregister_device(fintek->rdev); + rc_unregister_ir_raw_device(fintek->rdev); kfree(fintek); } diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 7d01560..ff30bdb 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -20,7 +20,7 @@ #include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/irq.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include <media/gpio-ir-recv.h> #define GPIO_IR_DRIVER_NAME "gpio-rc-recv" @@ -135,7 +135,6 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) } 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; @@ -161,7 +160,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) if (rc < 0) goto err_gpio_direction_input; - rc = rc_register_device(rcdev); + rc = rc_register_ir_raw_device(rcdev); if (rc < 0) { dev_err(&pdev->dev, "failed to register rc device\n"); goto err_register_rc_device; @@ -179,7 +178,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) return 0; err_request_irq: - rc_unregister_device(rcdev); + rc_unregister_ir_raw_device(rcdev); rcdev = NULL; err_register_rc_device: err_gpio_direction_input: @@ -196,7 +195,7 @@ static int gpio_ir_recv_remove(struct platform_device *pdev) struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); - rc_unregister_device(gpio_dev->rcdev); + rc_unregister_ir_raw_device(gpio_dev->rcdev); gpio_free(gpio_dev->gpio_nr); kfree(gpio_dev); return 0; diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 8a4baf5..3b7327a 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -25,7 +25,7 @@ #include <linux/usb/input.h> #include <linux/slab.h> #include <linux/completion.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #define DRIVER_NAME "iguanair" #define BUF_SIZE 152 @@ -513,7 +513,6 @@ static int iguanair_probe(struct usb_interface *intf, rc->input_phys = ir->phys; usb_to_input_id(ir->udev, &rc->input_id); rc->dev.parent = &intf->dev; - rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protocols = RC_BIT_ALL; rc->priv = ir; rc->open = iguanair_open; @@ -529,7 +528,7 @@ static int iguanair_probe(struct usb_interface *intf, iguanair_set_tx_carrier(rc, 38000); iguanair_set_tx_mask(rc, 0); - ret = rc_register_device(rc); + ret = rc_register_ir_raw_device(rc); if (ret < 0) { dev_err(&intf->dev, "failed to register rc device %d", ret); goto out2; @@ -558,7 +557,7 @@ static void iguanair_disconnect(struct usb_interface *intf) { struct iguanair *ir = usb_get_intfdata(intf); - rc_unregister_device(ir->rc); + rc_unregister_ir_raw_device(ir->rc); usb_set_intfdata(intf, NULL); usb_kill_urb(ir->urb_in); usb_kill_urb(ir->urb_out); diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c index 5b6d8e9..95a4da1 100644 --- a/drivers/media/rc/img-ir/img-ir-raw.c +++ b/drivers/media/rc/img-ir/img-ir-raw.c @@ -8,7 +8,7 @@ */ #include <linux/spinlock.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include "img-ir.h" #define ECHO_TIMEOUT_MS 150 /* ms between echos */ @@ -112,10 +112,9 @@ int img_ir_probe_raw(struct img_ir_priv *priv) } rdev->priv = priv; rdev->input_name = "IMG Infrared Decoder Raw"; - rdev->driver_type = RC_DRIVER_IR_RAW; /* Register raw decoder */ - error = rc_register_device(rdev); + error = rc_register_ir_raw_device(rdev); if (error) { dev_err(priv->dev, "failed to register raw IR input device\n"); rc_free_device(rdev); @@ -144,7 +143,7 @@ void img_ir_remove_raw(struct img_ir_priv *priv) img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE); spin_unlock_irq(&priv->lock); - rc_unregister_device(rdev); + rc_unregister_ir_raw_device(rdev); del_timer_sync(&raw->timer); } diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 2461933..1aa2ac0 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -1875,7 +1875,6 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) 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; diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 0d404a2..795fbc6 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -40,7 +40,7 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/bitops.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include <linux/pci_ids.h> #include "ite-cir.h" @@ -1557,7 +1557,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id /* set up ir-core props */ rdev->priv = itdev; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = ite_open; rdev->close = ite_close; @@ -1586,7 +1585,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev->driver_name = ITE_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; - ret = rc_register_device(rdev); + ret = rc_register_ir_raw_device(rdev); if (ret) goto exit_free_dev_rdev; @@ -1607,7 +1606,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id exit_release_cir_addr: release_region(itdev->cir_addr, itdev->params.io_region_size); exit_unregister_device: - rc_unregister_device(rdev); + rc_unregister_ir_raw_device(rdev); rdev = NULL; exit_free_dev_rdev: rc_free_device(rdev); @@ -1634,7 +1633,7 @@ static void ite_remove(struct pnp_dev *pdev) free_irq(dev->cir_irq, dev); release_region(dev->cir_addr, dev->params.io_region_size); - rc_unregister_device(dev->rdev); + rc_unregister_ir_raw_device(dev->rdev); kfree(dev); } diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index e0c8552..eac87ec 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -43,7 +43,7 @@ #include <linux/usb.h> #include <linux/usb/input.h> #include <linux/pm_wakeup.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #define DRIVER_VERSION "1.92" #define DRIVER_AUTHOR "Jarod Wilson <jarod@xxxxxxxxxx>" @@ -1217,7 +1217,6 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) usb_to_input_id(ir->usbdev, &rc->input_id); rc->dev.parent = dev; rc->priv = ir; - rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protocols = RC_BIT_ALL; rc->timeout = MS_TO_NS(100); if (!ir->flags.no_tx) { @@ -1229,7 +1228,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) rc->map_name = mceusb_model[ir->model].rc_map ? mceusb_model[ir->model].rc_map : RC_MAP_RC6_MCE; - ret = rc_register_device(rc); + ret = rc_register_ir_raw_device(rc); if (ret < 0) { dev_err(dev, "remote dev registration failed"); goto out; @@ -1414,7 +1413,7 @@ static void mceusb_dev_disconnect(struct usb_interface *intf) return; ir->usbdev = NULL; - rc_unregister_device(ir->rc); + rc_unregister_ir_raw_device(ir->rc); usb_kill_urb(ir->urb_in); usb_free_urb(ir->urb_in); usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 160d685..a8c9b5f 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -34,7 +34,7 @@ #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/slab.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include <linux/pci_ids.h> #include "nuvoton-cir.h" @@ -1054,7 +1054,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* Set up the rc device */ rdev->priv = nvt; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = nvt_open; rdev->close = nvt_close; @@ -1119,7 +1118,7 @@ exit_free_irq: exit_release_cir_addr: release_region(nvt->cir_addr, CIR_IOREG_LENGTH); exit_unregister_device: - rc_unregister_device(rdev); + rc_unregister_ir_raw_device(rdev); rdev = NULL; exit_free_dev_rdev: rc_free_device(rdev); @@ -1147,7 +1146,7 @@ static void nvt_remove(struct pnp_dev *pdev) release_region(nvt->cir_addr, CIR_IOREG_LENGTH); release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); - rc_unregister_device(nvt->rdev); + rc_unregister_ir_raw_device(nvt->rdev); kfree(nvt); } diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 0159836..0b32ef8 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -19,6 +19,12 @@ #include <linux/slab.h> #include <linux/spinlock.h> #include <media/rc-core.h> +#include <media/rc-ir-raw.h> + +enum rc_driver_type { + RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */ + RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */ +}; struct ir_raw_handler { struct list_head list; @@ -148,12 +154,8 @@ static inline bool is_timing_event(struct ir_raw_event ev) /* * Routines from rc-raw.c to be used internally and by decoders */ -u64 ir_raw_get_allowed_protocols(void); -int ir_raw_event_register(struct rc_dev *dev); -void ir_raw_event_unregister(struct rc_dev *dev); int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); -void ir_raw_init(void); /* * Methods from rc-keytable.c to be used internally diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 5ed8007..86f5aa7 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -16,6 +16,7 @@ #include <linux/kthread.h> #include <linux/mutex.h> #include <linux/kmod.h> +#include <linux/module.h> #include <linux/sched.h> #include <linux/freezer.h> #include "rc-core-priv.h" @@ -269,8 +270,7 @@ void ir_raw_event_handle(struct rc_dev *dev) EXPORT_SYMBOL_GPL(ir_raw_event_handle); /* used internally by the sysfs interface */ -u64 -ir_raw_get_allowed_protocols(void) +static u64 ir_raw_get_allowed_protocols(struct rc_dev *dev) { u64 protocols; mutex_lock(&ir_raw_handler_lock); @@ -287,7 +287,7 @@ static int change_protocol(struct rc_dev *dev, u64 *rc_type) { /* * Used to (un)register raw event clients */ -int ir_raw_event_register(struct rc_dev *dev) +int rc_register_ir_raw_device(struct rc_dev *dev) { int rc; struct ir_raw_handler *handler; @@ -301,14 +301,16 @@ int ir_raw_event_register(struct rc_dev *dev) dev->raw->dev = dev; dev->enabled_protocols = ~0; + dev->get_protocols = ir_raw_get_allowed_protocols; + dev->driver_type = RC_DRIVER_IR_RAW; dev->change_protocol = change_protocol; + spin_lock_init(&dev->raw->lock); rc = kfifo_alloc(&dev->raw->kfifo, sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, GFP_KERNEL); if (rc < 0) goto out; - spin_lock_init(&dev->raw->lock); dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, dev_name(&dev->dev)); @@ -317,6 +319,10 @@ int ir_raw_event_register(struct rc_dev *dev) goto out; } + rc = rc_register_device(dev); + if (rc < 0) + goto out_thread; + mutex_lock(&ir_raw_handler_lock); list_add_tail(&dev->raw->list, &ir_raw_client_list); list_for_each_entry(handler, &ir_raw_handler_list, list) @@ -326,13 +332,16 @@ int ir_raw_event_register(struct rc_dev *dev) return 0; +out_thread: + kthread_stop(dev->raw->thread); out: kfree(dev->raw); dev->raw = NULL; return rc; } +EXPORT_SYMBOL_GPL(rc_register_ir_raw_device); -void ir_raw_event_unregister(struct rc_dev *dev) +void rc_unregister_ir_raw_device(struct rc_dev *dev) { struct ir_raw_handler *handler; @@ -351,7 +360,9 @@ void ir_raw_event_unregister(struct rc_dev *dev) kfifo_free(&dev->raw->kfifo); kfree(dev->raw); dev->raw = NULL; + rc_unregister_device(dev); } +EXPORT_SYMBOL_GPL(rc_unregister_ir_raw_device); /* * Extension interface - used to register the IR decoders @@ -387,10 +398,11 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) } EXPORT_SYMBOL(ir_raw_handler_unregister); -void ir_raw_init(void) +static struct work_struct wq_load; + +static void rc_ir_raw_init_decoders(struct work_struct *work) { /* Load the decoder modules */ - load_nec_decode(); load_rc5_decode(); load_rc6_decode(); @@ -400,8 +412,15 @@ void ir_raw_init(void) load_sharp_decode(); load_mce_kbd_decode(); load_lirc_codec(); +} - /* If needed, we may later add some init code. In this case, - it is needed to change the CONFIG_MODULE test at rc-core.h - */ +static int __init rc_ir_raw_init(void) +{ + INIT_WORK(&wq_load, rc_ir_raw_init_decoders); + schedule_work(&wq_load); + return 0; } +subsys_initcall(rc_ir_raw_init); + +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index f201395..343c8d0 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -26,7 +26,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/sched.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #define DRIVER_NAME "rc-loopback" #define dprintk(x...) if (debug) printk(KERN_INFO DRIVER_NAME ": " x) @@ -227,7 +227,6 @@ static int __init loop_init(void) rc->input_id.version = 1; rc->driver_name = DRIVER_NAME; rc->priv = &loopdev; - rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protocols = RC_BIT_ALL; rc->timeout = 100 * 1000 * 1000; /* 100 ms */ rc->min_timeout = 1; @@ -250,7 +249,7 @@ static int __init loop_init(void) loopdev.learning = false; loopdev.carrierreport = false; - ret = rc_register_device(rc); + ret = rc_register_ir_raw_device(rc); if (ret < 0) { printk(KERN_ERR DRIVER_NAME ": rc_dev registration failed\n"); rc_free_device(rc); @@ -263,7 +262,7 @@ static int __init loop_init(void) static void __exit loop_exit(void) { - rc_unregister_device(loopdev.dev); + rc_unregister_ir_raw_device(loopdev.dev); } module_init(loop_init); diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 8729d0a..7caca4f 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -343,10 +343,7 @@ static ssize_t show_protocols(struct device *device, if (fattr->type == RC_FILTER_NORMAL) { enabled = dev->enabled_protocols; - if (dev->raw) - allowed = ir_raw_get_allowed_protocols(); - else - allowed = dev->allowed_protocols; + allowed = dev->allowed_protocols; } else { enabled = dev->enabled_wakeup_protocols; allowed = dev->allowed_wakeup_protocols; @@ -919,10 +916,7 @@ void rc_init_ir_rx(struct rc_dev *dev, struct rc_ir_rx *rx) rx->rx_enabled = 0x1; rx->rx_connected = 0x1; rx->protocols_enabled[0] = dev->enabled_protocols; - if (dev->driver_type == RC_DRIVER_SCANCODE) - rx->protocols_supported[0] = dev->allowed_protocols; - else - rx->protocols_supported[0] = ir_raw_get_allowed_protocols(); + rx->protocols_supported[0] = dev->allowed_protocols; rx->timeout = dev->timeout; rx->timeout_min = dev->min_timeout; rx->timeout_max = dev->max_timeout; @@ -1135,9 +1129,6 @@ static void rc_dev_release(struct device *device) { struct rc_dev *dev = to_rc_dev(device); - if (dev->driver_type == RC_DRIVER_IR_RAW) - ir_raw_event_unregister(dev); - kfifo_free(&dev->txfifo); kfree(dev); module_put(THIS_MODULE); @@ -1267,7 +1258,6 @@ EXPORT_SYMBOL_GPL(rc_free_device); int rc_register_device(struct rc_dev *dev) { - static bool raw_init = false; /* raw decoders loaded? */ struct rc_map *rc_map = NULL; int attr = 0; int minor; @@ -1290,18 +1280,6 @@ int rc_register_device(struct rc_dev *dev) goto out_minor; } - if (dev->driver_type == RC_DRIVER_IR_RAW) { - /* Load raw decoders, if they aren't already */ - if (!raw_init) { - IR_dprintk(1, "Loading raw decoders\n"); - ir_raw_init(); - raw_init = true; - } - rc = ir_raw_event_register(dev); - if (rc < 0) - goto out_minor; - } - dev->dev.groups = dev->sysfs_groups; dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp; if (dev->s_filter) @@ -1319,13 +1297,13 @@ int rc_register_device(struct rc_dev *dev) u64 rc_type = (1 << rc_map->scan[0].protocol); rc = dev->change_protocol(dev, &rc_type); if (rc < 0) - goto out_raw; + goto out_minor; dev->enabled_protocols = rc_type; } rc = cdev_add(&dev->cdev, dev->dev.devt, 1); if (rc) - goto out_raw; + goto out_minor; rc = device_add(&dev->dev); if (rc) @@ -1347,9 +1325,6 @@ out_dev: device_del(&dev->dev); out_cdev: cdev_del(&dev->cdev); -out_raw: - if (dev->driver_type == RC_DRIVER_IR_RAW) - ir_raw_event_unregister(dev); out_minor: ida_simple_remove(&rc_ida, minor); return rc; @@ -1377,9 +1352,6 @@ void rc_unregister_device(struct rc_dev *dev) cdev_del(&dev->cdev); - if (dev->driver_type == RC_DRIVER_IR_RAW) - ir_raw_event_unregister(dev); - for (i = 0; i < ARRAY_SIZE(dev->keytables); i++) rc_remove_keytable(dev, i); diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 3a931a5..17974bf 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -52,7 +52,7 @@ #include <linux/slab.h> #include <linux/usb.h> #include <linux/usb/input.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> /* Driver Information */ #define DRIVER_AUTHOR "Jarod Wilson <jarod@xxxxxxxxxx>" @@ -936,7 +936,6 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) usb_to_input_id(rr3->udev, &rc->input_id); rc->dev.parent = dev; rc->priv = rr3; - rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protocols = RC_BIT_ALL; rc->timeout = US_TO_NS(2750); rc->tx_ir = redrat3_transmit_ir; @@ -945,7 +944,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) rc->rx_resolution = US_TO_NS(2); rc->map_name = RC_MAP_HAUPPAUGE; - ret = rc_register_device(rc); + ret = rc_register_ir_raw_device(rc); if (ret < 0) { dev_err(dev, "remote dev registration failed\n"); goto out; @@ -1114,7 +1113,7 @@ static void redrat3_dev_disconnect(struct usb_interface *intf) return; usb_set_intfdata(intf, NULL); - rc_unregister_device(rr3->rc); + rc_unregister_ir_raw_device(rr3->rc); led_classdev_unregister(&rr3->led); del_timer_sync(&rr3->rx_timeout); redrat3_delete(rr3, udev); diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 2659f66..149e824 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -36,7 +36,7 @@ #include <linux/slab.h> #include <linux/usb.h> #include <linux/usb/input.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #define DRIVER_VERSION "1.61" #define DRIVER_NAME "streamzap" @@ -314,12 +314,11 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) usb_to_input_id(sz->usbdev, &rdev->input_id); rdev->dev.parent = dev; rdev->priv = sz; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->driver_name = DRIVER_NAME; rdev->map_name = RC_MAP_STREAMZAP; - ret = rc_register_device(rdev); + ret = rc_register_ir_raw_device(rdev); if (ret < 0) { dev_err(dev, "remote input device register failed\n"); goto out; @@ -484,7 +483,7 @@ static void streamzap_disconnect(struct usb_interface *interface) return; sz->usbdev = NULL; - rc_unregister_device(sz->rdev); + rc_unregister_ir_raw_device(sz->rdev); usb_kill_urb(sz->urb_in); 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/ttusbir.c b/drivers/media/rc/ttusbir.c index bc214e2..19317e2 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -23,7 +23,7 @@ #include <linux/usb/input.h> #include <linux/slab.h> #include <linux/leds.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #define DRIVER_NAME "ttusbir" #define DRIVER_DESC "TechnoTrend USB IR Receiver" @@ -317,7 +317,6 @@ static int ttusbir_probe(struct usb_interface *intf, rc->input_phys = tt->phys; usb_to_input_id(tt->udev, &rc->input_id); rc->dev.parent = &intf->dev; - rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protocols = RC_BIT_ALL; rc->priv = tt; rc->driver_name = DRIVER_NAME; @@ -329,7 +328,7 @@ static int ttusbir_probe(struct usb_interface *intf, */ rc->rx_resolution = NS_PER_BIT; - ret = rc_register_device(rc); + ret = rc_register_ir_raw_device(rc); if (ret) { dev_err(&intf->dev, "failed to register rc device %d\n", ret); goto out2; @@ -347,7 +346,7 @@ static int ttusbir_probe(struct usb_interface *intf, return 0; out3: - rc_unregister_device(rc); + rc_unregister_ir_raw_device(rc); rc = NULL; out2: led_classdev_unregister(&tt->led); @@ -378,7 +377,7 @@ static void ttusbir_disconnect(struct usb_interface *intf) tt->udev = NULL; - rc_unregister_device(tt->rc); + rc_unregister_ir_raw_device(tt->rc); led_classdev_unregister(&tt->led); for (i = 0; i < NUM_URBS; i++) { usb_kill_urb(tt->urb[i]); diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 8871109..07da3e0 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -54,7 +54,7 @@ #include <linux/slab.h> #include <linux/wait.h> #include <linux/sched.h> -#include <media/rc-core.h> +#include <media/rc-ir-raw.h> #define DRVNAME "winbond-cir" @@ -1051,7 +1051,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) 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"; @@ -1071,7 +1070,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->rx_resolution = US_TO_NS(2); data->dev->allowed_protocols = RC_BIT_ALL; - err = rc_register_device(data->dev); + err = rc_register_ir_raw_device(data->dev); if (err) goto exit_free_rc; @@ -1117,7 +1116,7 @@ exit_release_ebase: exit_release_wbase: release_region(data->wbase, WAKEUP_IOMEM_LEN); exit_unregister_device: - rc_unregister_device(data->dev); + rc_unregister_ir_raw_device(data->dev); data->dev = NULL; exit_free_rc: rc_free_device(data->dev); @@ -1148,7 +1147,7 @@ wbcir_remove(struct pnp_dev *device) /* Clear BUFF_EN, END_EN, MATCH_EN */ wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); - rc_unregister_device(data->dev); + rc_unregister_ir_raw_device(data->dev); led_classdev_unregister(&data->led); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index 124b4ba..ccdf0c6 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -25,6 +25,7 @@ #include <linux/usb/input.h> #include <linux/firmware.h> #include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include "dvb_frontend.h" #include "dvb_demux.h" @@ -131,7 +132,7 @@ struct dvb_usb_driver_info { * @change_protocol: callback to change protocol * @query: called to query an event from the device * @interval: time in ms between two queries - * @driver_type: used to point if a device supports raw mode + * @rc_raw: used to point if a device supports raw mode * @bulk_mode: device supports bulk mode for rc (disable polling mode) */ struct dvb_usb_rc { @@ -140,7 +141,7 @@ struct dvb_usb_rc { int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); int (*query) (struct dvb_usb_device *d); unsigned int interval; - enum rc_driver_type driver_type; + bool rc_raw; bool bulk_mode; }; diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index eaa76ef..ea84894b 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -163,12 +163,15 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d) /* 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; - ret = rc_register_device(dev); + if (d->rc.rc_raw) + ret = rc_register_ir_raw_device(dev); + else + ret = rc_register_device(dev); + if (ret < 0) { rc_free_device(dev); goto err; @@ -201,7 +204,10 @@ static int dvb_usbv2_remote_exit(struct dvb_usb_device *d) if (d->rc_dev) { cancel_delayed_work_sync(&d->rc_query_work); - rc_unregister_device(d->rc_dev); + if (d->rc.rc_raw) + rc_unregister_ir_raw_device(d->rc_dev); + else + rc_unregister_device(d->rc_dev); d->rc_dev = NULL; } diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 15f1e70..0412862 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1373,7 +1373,7 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d, return rtl28xx_wr_reg(d, IR_RX_IE, 0x00); rc->allowed_protos = RC_BIT_ALL; - rc->driver_type = RC_DRIVER_IR_RAW; + rc->rc_raw = true; rc->query = rtl2832u_rc_query; rc->interval = 400; diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c index 5986626..88574d0 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c @@ -273,14 +273,17 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) 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; dev->dev.parent = &d->udev->dev; dev->priv = d; - err = rc_register_device(dev); + if (d->props.rc.core.rc_raw) + err = rc_register_ir_raw_device(dev); + else + err = rc_register_device(dev); + if (err < 0) { rc_free_device(dev); return err; @@ -341,6 +344,8 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d) cancel_delayed_work_sync(&d->rc_query_work); if (d->props.rc.mode == DVB_RC_LEGACY) input_unregister_device(d->input_dev); + else if (d->props.rc.core.rc_raw) + rc_unregister_ir_raw_device(d->rc_dev); else rc_unregister_device(d->rc_dev); } diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h index ce4c4e3..8e4b31e 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb.h +++ b/drivers/media/usb/dvb-usb/dvb-usb.h @@ -15,6 +15,7 @@ #include <linux/firmware.h> #include <linux/mutex.h> #include <media/rc-core.h> +#include <media/rc-ir-raw.h> #include "dvb_frontend.h" #include "dvb_demux.h" @@ -191,7 +192,7 @@ struct dvb_rc_legacy { * @rc_codes: name of rc codes table * @protocol: type of protocol(s) currently used by the driver * @allowed_protos: protocol(s) supported by the driver - * @driver_type: Used to point if a device supports raw mode + * @rc_raw: Used to point if a device supports raw mode * @change_protocol: callback to change protocol * @rc_query: called to query an event event. * @rc_interval: time in ms between two queries. @@ -201,7 +202,7 @@ struct dvb_rc { char *rc_codes; u64 protocol; u64 allowed_protos; - enum rc_driver_type driver_type; + bool rc_raw; int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); char *module_name; int (*rc_query) (struct dvb_usb_device *d); diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index 98d24ae..288f24c 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c @@ -733,7 +733,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = { .module_name = "technisat-usb2", .rc_query = technisat_usb2_rc_query, .allowed_protos = RC_BIT_ALL, - .driver_type = RC_DRIVER_IR_RAW, + .rc_raw = true, } }; diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 1232e32..8fdb515 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -856,9 +856,6 @@ static int em28xx_ir_suspend(struct em28xx *dev) if (ir) cancel_delayed_work_sync(&ir->work); cancel_delayed_work_sync(&dev->buttons_query_work); - /* is canceling delayed work sufficient or does the rc event - kthread needs stopping? kthread is stopped in - ir_raw_event_unregister() */ return 0; } @@ -870,8 +867,6 @@ static int em28xx_ir_resume(struct em28xx *dev) return 0; em28xx_info("Resuming input extension"); - /* if suspend calls ir_raw_event_unregister(), the should call - ir_raw_event_register() */ if (ir) schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); if (dev->num_button_polling_addresses) diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c index 7c9b58d..1d4b191 100644 --- a/drivers/media/usb/tm6000/tm6000-input.c +++ b/drivers/media/usb/tm6000/tm6000-input.c @@ -452,7 +452,6 @@ int tm6000_ir_init(struct tm6000_core *dev) 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); diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 228510e..25c1d38 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -177,11 +177,6 @@ struct rc_keytable_ioctl { char name[RC_KEYTABLE_NAME_SIZE]; } __packed; -enum rc_driver_type { - RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */ - RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */ -}; - /* This is used for the input EVIOC[SG]KEYCODE_V2 ioctls */ struct rc_scancode { __u16 protocol; @@ -304,6 +299,7 @@ enum rc_filter_type { * @rx_resolution : resolution (in ns) of input sampler * @tx_resolution: resolution (in ns) of output sampler * @change_protocol: allow changing the protocol used on hardware decoders + * @get_protocols: returns a bitmask of allowed protocols * @change_wakeup_protocol: allow changing the protocol used for wakeup * filtering * @open: callback to allow drivers to enable polling/irq when IR input device @@ -347,7 +343,7 @@ struct rc_dev { wait_queue_head_t txwait; wait_queue_head_t rxwait; struct ir_raw_event_ctrl *raw; - enum rc_driver_type driver_type; + unsigned driver_type; bool idle; u64 allowed_protocols; u64 enabled_protocols; @@ -363,6 +359,7 @@ struct rc_dev { u32 max_timeout; u32 rx_resolution; u32 tx_resolution; + u64 (*get_protocols)(struct rc_dev *dev); int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); int (*change_wakeup_protocol)(struct rc_dev *dev, u64 *rc_type); int (*open)(struct rc_dev *dev); @@ -461,70 +458,6 @@ static inline void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protoco rc_do_keydown(dev, protocol, scancode, toggle, false); } -/* - * From rc-raw.c - * The Raw interface is specific to InfraRed. It may be a good idea to - * split it later into a separate header. - */ - -enum raw_event_type { - IR_SPACE = (1 << 0), - IR_PULSE = (1 << 1), - IR_START_EVENT = (1 << 2), - IR_STOP_EVENT = (1 << 3), -}; - -struct ir_raw_event { - union { - u32 duration; - - struct { - u32 carrier; - u8 duty_cycle; - }; - }; - - unsigned pulse:1; - unsigned reset:1; - unsigned timeout:1; - unsigned carrier_report:1; -}; - -#define DEFINE_IR_RAW_EVENT(event) \ - struct ir_raw_event event = { \ - { .duration = 0 } , \ - .pulse = 0, \ - .reset = 0, \ - .timeout = 0, \ - .carrier_report = 0 } - -static inline void init_ir_raw_event(struct ir_raw_event *ev) -{ - memset(ev, 0, sizeof(*ev)); -} - -#define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */ -#define US_TO_NS(usec) ((usec) * 1000) -#define MS_TO_US(msec) ((msec) * 1000) -#define MS_TO_NS(msec) ((msec) * 1000 * 1000) - -void ir_raw_event_handle(struct rc_dev *dev); -int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); -int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type); -int ir_raw_event_store_with_filter(struct rc_dev *dev, - struct ir_raw_event *ev); -void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); -int ir_raw_get_tx_event(struct rc_dev *dev, struct rc_event *ev); - -static inline void ir_raw_event_reset(struct rc_dev *dev) -{ - DEFINE_IR_RAW_EVENT(ev); - ev.reset = true; - - ir_raw_event_store(dev, &ev); - ir_raw_event_handle(dev); -} - /* extract mask bits out of data and pack them into the result */ static inline u32 ir_extract_bits(u32 data, u32 mask) { diff --git a/include/media/rc-ir-raw.h b/include/media/rc-ir-raw.h new file mode 100644 index 0000000..dad3eb2 --- /dev/null +++ b/include/media/rc-ir-raw.h @@ -0,0 +1,83 @@ +/* + * Remote Controller core header + * + * Copyright (C) 2009-2010 by Mauro Carvalho Chehab + * + * 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 version 2 of the License. + * + * 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. + */ + +#ifndef _RC_IR_RAW +#define _RC_IR_RAW + +#include <linux/spinlock.h> +#include <linux/kfifo.h> +#include <media/rc-core.h> + +enum raw_event_type { + IR_SPACE = (1 << 0), + IR_PULSE = (1 << 1), + IR_START_EVENT = (1 << 2), + IR_STOP_EVENT = (1 << 3), +}; + +struct ir_raw_event { + union { + u32 duration; + + struct { + u32 carrier; + u8 duty_cycle; + }; + }; + + unsigned pulse:1; + unsigned reset:1; + unsigned timeout:1; + unsigned carrier_report:1; +}; + +#define DEFINE_IR_RAW_EVENT(event) \ + struct ir_raw_event event = { \ + { .duration = 0 } , \ + .pulse = 0, \ + .reset = 0, \ + .timeout = 0, \ + .carrier_report = 0 } + +static inline void init_ir_raw_event(struct ir_raw_event *ev) +{ + memset(ev, 0, sizeof(*ev)); +} + +#define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */ +#define US_TO_NS(usec) ((usec) * 1000) +#define MS_TO_US(msec) ((msec) * 1000) +#define MS_TO_NS(msec) ((msec) * 1000 * 1000) + +void ir_raw_event_handle(struct rc_dev *dev); +int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); +int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type); +int ir_raw_event_store_with_filter(struct rc_dev *dev, + struct ir_raw_event *ev); +void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); +int ir_raw_get_tx_event(struct rc_dev *dev, struct rc_event *ev); +int rc_register_ir_raw_device(struct rc_dev *dev); +void rc_unregister_ir_raw_device(struct rc_dev *dev); + +static inline void ir_raw_event_reset(struct rc_dev *dev) +{ + DEFINE_IR_RAW_EVENT(ev); + ev.reset = true; + + ir_raw_event_store(dev, &ev); + ir_raw_event_handle(dev); +} + +#endif /* _RC_IR_RAW */ -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html