The lirc bridge exists as a raw decoder. We would like to make the bridge
to also work for scancode drivers in further commits, so it cannot be
a raw decoder.

Note that rc-code, lirc_dev, ir-lirc-codec are now calling functions of
each other, so they've been merged into one module rc-core to avoid
circular dependencies.

Signed-off-by: Sean Young <s...@mess.org>
---
 drivers/media/rc/Kconfig         |  15 +++--
 drivers/media/rc/Makefile        |   6 +-
 drivers/media/rc/ir-lirc-codec.c | 117 ++++++++++++---------------------------
 drivers/media/rc/lirc_dev.c      |  18 +-----
 drivers/media/rc/rc-core-priv.h  |  38 ++++++-------
 drivers/media/rc/rc-ir-raw.c     |   4 +-
 drivers/media/rc/rc-main.c       |  21 +++++--
 include/media/rc-core.h          |   7 +++
 8 files changed, 92 insertions(+), 134 deletions(-)

diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index ddfab25..efdd6f7 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -6,14 +6,8 @@ config RC_CORE
 
 source "drivers/media/rc/keymaps/Kconfig"
 
-menuconfig RC_DECODERS
-        bool "Remote controller decoders"
-       depends on RC_CORE
-       default y
-
-if RC_DECODERS
 config LIRC
-       tristate "LIRC interface driver"
+       bool "LIRC interface driver"
        depends on RC_CORE
 
        ---help---
@@ -24,7 +18,7 @@ config LIRC
           encoding for IR transmitting (aka "blasting").
 
 config IR_LIRC_CODEC
-       tristate "Enable IR to LIRC bridge"
+       bool "Enable IR to LIRC bridge"
        depends on RC_CORE
        depends on LIRC
        default y
@@ -33,7 +27,12 @@ config IR_LIRC_CODEC
           Enable this option to pass raw IR to and from userspace via
           the LIRC interface.
 
+menuconfig RC_DECODERS
+       bool "Remote controller decoders"
+       depends on RC_CORE
+       default y
 
+if RC_DECODERS
 config IR_NEC_DECODER
        tristate "Enable IR raw decoder for the NEC protocol"
        depends on RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 379a5c0..c8e7b38 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,9 +1,10 @@
-rc-core-objs   := rc-main.o rc-ir-raw.o
 
 obj-y += keymaps/
 
 obj-$(CONFIG_RC_CORE) += rc-core.o
-obj-$(CONFIG_LIRC) += lirc_dev.o
+rc-core-y := rc-main.o rc-ir-raw.o
+rc-core-$(CONFIG_LIRC) += lirc_dev.o
+rc-core-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
 obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
 obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
 obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
@@ -12,7 +13,6 @@ obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
 obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
 obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o
 obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
-obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
 obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o
 
 # stand-alone IR receivers/transmitters
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 17fd956..475f6af 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -14,7 +14,6 @@
 
 #include <linux/sched.h>
 #include <linux/wait.h>
-#include <linux/module.h>
 #include <media/lirc.h>
 #include <media/lirc_dev.h>
 #include <media/rc-core.h>
@@ -30,15 +29,12 @@
  *
  * This function returns -EINVAL if the lirc interfaces aren't wired up.
  */
-static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
+int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
 {
-       struct lirc_codec *lirc = &dev->raw->lirc;
+       struct lirc_driver *lirc = dev->lirc;
        int sample;
 
-       if (!(dev->enabled_protocols & RC_BIT_LIRC))
-               return 0;
-
-       if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
+       if (!lirc || !lirc->rbuf)
                return -EINVAL;
 
        /* Packet start */
@@ -59,14 +55,14 @@ static int ir_lirc_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
        /* Packet end */
        } else if (ev.timeout) {
 
-               if (lirc->gap)
+               if (dev->gap)
                        return 0;
 
-               lirc->gap_start = ktime_get();
-               lirc->gap = true;
-               lirc->gap_duration = ev.duration;
+               dev->gap_start = ktime_get();
+               dev->gap = true;
+               dev->gap_duration = ev.duration;
 
-               if (!lirc->send_timeout_reports)
+               if (!dev->send_timeout_reports)
                        return 0;
 
                sample = LIRC_TIMEOUT(ev.duration / 1000);
@@ -75,21 +71,21 @@ static int ir_lirc_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
        /* Normal sample */
        } else {
 
-               if (lirc->gap) {
+               if (dev->gap) {
                        int gap_sample;
 
-                       lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
-                               lirc->gap_start));
+                       dev->gap_duration += ktime_to_ns(
+                               ktime_sub(ktime_get(), dev->gap_start));
 
                        /* Convert to ms and cap by LIRC_VALUE_MASK */
-                       do_div(lirc->gap_duration, 1000);
-                       lirc->gap_duration = min(lirc->gap_duration,
-                                                       (u64)LIRC_VALUE_MASK);
+                       do_div(dev->gap_duration, 1000);
+                       dev->gap_duration = min_t(u64, dev->gap_duration,
+                                                       LIRC_VALUE_MASK);
 
-                       gap_sample = LIRC_SPACE(lirc->gap_duration);
-                       lirc_buffer_write(dev->raw->lirc.drv->rbuf,
+                       gap_sample = LIRC_SPACE(dev->gap_duration);
+                       lirc_buffer_write(lirc->rbuf,
                                                (unsigned char *) &gap_sample);
-                       lirc->gap = false;
+                       dev->gap = false;
                }
 
                sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
@@ -98,9 +94,9 @@ static int ir_lirc_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
                           TO_US(ev.duration), TO_STR(ev.pulse));
        }
 
-       lirc_buffer_write(dev->raw->lirc.drv->rbuf,
+       lirc_buffer_write(lirc->rbuf,
                          (unsigned char *) &sample);
-       wake_up(&dev->raw->lirc.drv->rbuf->wait_poll);
+       wake_up(&lirc->rbuf->wait_poll);
 
        return 0;
 }
@@ -108,7 +104,6 @@ static int ir_lirc_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
 static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
                                   size_t n, loff_t *ppos)
 {
-       struct lirc_codec *lirc;
        struct rc_dev *dev;
        unsigned int *txbuf; /* buffer with values to transmit */
        ssize_t ret = -EINVAL;
@@ -120,8 +115,8 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
 
        start = ktime_get();
 
-       lirc = lirc_get_pdata(file);
-       if (!lirc)
+       dev = lirc_get_pdata(file);
+       if (!dev || !dev->lirc)
                return -EFAULT;
 
        if (n < sizeof(unsigned) || n % sizeof(unsigned))
@@ -135,12 +130,6 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
        if (IS_ERR(txbuf))
                return PTR_ERR(txbuf);
 
-       dev = lirc->dev;
-       if (!dev) {
-               ret = -EFAULT;
-               goto out;
-       }
-
        if (!dev->tx_ir) {
                ret = -ENOSYS;
                goto out;
@@ -183,18 +172,13 @@ out:
 static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
                        unsigned long arg)
 {
-       struct lirc_codec *lirc;
        struct rc_dev *dev;
        u32 __user *argp = (u32 __user *)(arg);
        int ret = 0;
        __u32 val = 0, tmp;
 
-       lirc = lirc_get_pdata(filep);
-       if (!lirc)
-               return -EFAULT;
-
-       dev = lirc->dev;
-       if (!dev)
+       dev  = lirc_get_pdata(filep);
+       if (!dev || !dev->lirc)
                return -EFAULT;
 
        if (_IOC_DIR(cmd) & _IOC_WRITE) {
@@ -253,14 +237,14 @@ static long ir_lirc_ioctl(struct file *filep, unsigned 
int cmd,
                        return -EINVAL;
 
                return dev->s_rx_carrier_range(dev,
-                                              dev->raw->lirc.carrier_low,
+                                              dev->carrier_low,
                                               val);
 
        case LIRC_SET_REC_CARRIER_RANGE:
                if (val <= 0)
                        return -EINVAL;
 
-               dev->raw->lirc.carrier_low = val;
+               dev->carrier_low = val;
                return 0;
 
        case LIRC_GET_REC_RESOLUTION:
@@ -306,7 +290,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
                break;
 
        case LIRC_SET_REC_TIMEOUT_REPORTS:
-               lirc->send_timeout_reports = !!val;
+               dev->send_timeout_reports = !!val;
                break;
 
        default:
@@ -343,7 +327,7 @@ static const struct file_operations lirc_fops = {
        .llseek         = no_llseek,
 };
 
-static int ir_lirc_register(struct rc_dev *dev)
+int ir_lirc_register(struct rc_dev *dev)
 {
        struct lirc_driver *drv;
        struct lirc_buffer *rbuf;
@@ -390,7 +374,7 @@ static int ir_lirc_register(struct rc_dev *dev)
                 dev->driver_name);
        drv->minor = -1;
        drv->features = features;
-       drv->data = &dev->raw->lirc;
+       drv->data = dev;
        drv->rbuf = rbuf;
        drv->set_use_inc = &ir_lirc_open;
        drv->set_use_dec = &ir_lirc_close;
@@ -406,8 +390,7 @@ static int ir_lirc_register(struct rc_dev *dev)
                goto lirc_register_failed;
        }
 
-       dev->raw->lirc.drv = drv;
-       dev->raw->lirc.dev = dev;
+       dev->lirc = drv;
        return 0;
 
 lirc_register_failed:
@@ -419,41 +402,11 @@ rbuf_alloc_failed:
        return rc;
 }
 
-static int ir_lirc_unregister(struct rc_dev *dev)
+void ir_lirc_unregister(struct rc_dev *dev)
 {
-       struct lirc_codec *lirc = &dev->raw->lirc;
-
-       lirc_unregister_driver(lirc->drv->minor);
-       lirc_buffer_free(lirc->drv->rbuf);
-       kfree(lirc->drv);
-
-       return 0;
-}
-
-static struct ir_raw_handler lirc_handler = {
-       .protocols      = RC_BIT_LIRC,
-       .decode         = ir_lirc_decode,
-       .raw_register   = ir_lirc_register,
-       .raw_unregister = ir_lirc_unregister,
-};
-
-static int __init ir_lirc_codec_init(void)
-{
-       ir_raw_handler_register(&lirc_handler);
-
-       printk(KERN_INFO "IR LIRC bridge handler initialized\n");
-       return 0;
-}
-
-static void __exit ir_lirc_codec_exit(void)
-{
-       ir_raw_handler_unregister(&lirc_handler);
+       if (dev->lirc) {
+               lirc_unregister_driver(dev->lirc->minor);
+               lirc_buffer_free(dev->lirc->rbuf);
+               kfree(dev->lirc);
+       }
 }
-
-module_init(ir_lirc_codec_init);
-module_exit(ir_lirc_codec_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jarod Wilson <ja...@redhat.com>");
-MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
-MODULE_DESCRIPTION("LIRC IR handler bridge");
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 4de0e85..44a61e81 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -39,8 +39,6 @@
 #include <media/lirc.h>
 #include <media/lirc_dev.h>
 
-static bool debug;
-
 #define IRCTL_DEV_NAME "BaseRemoteCtl"
 #define NOPLUG         -1
 #define LOGHEAD                "lirc_dev (%s[%d]): "
@@ -785,8 +783,7 @@ ssize_t lirc_dev_fop_write(struct file *file, const char 
__user *buffer,
 }
 EXPORT_SYMBOL(lirc_dev_fop_write);
 
-
-static int __init lirc_dev_init(void)
+int __init lirc_dev_init(void)
 {
        int retval;
 
@@ -813,21 +810,10 @@ error:
        return retval;
 }
 
-
-
-static void __exit lirc_dev_exit(void)
+void __exit lirc_dev_exit(void)
 {
        class_destroy(lirc_class);
        unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES);
        printk(KERN_INFO "lirc_dev: module unloaded\n");
 }
 
-module_init(lirc_dev_init);
-module_exit(lirc_dev_exit);
-
-MODULE_DESCRIPTION("LIRC base driver module");
-MODULE_AUTHOR("Artur Lipowski");
-MODULE_LICENSE("GPL");
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Enable debugging messages");
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index b68d4f76..732479d 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -26,7 +26,7 @@ struct ir_raw_handler {
        u64 protocols; /* which are handled by this handler */
        int (*decode)(struct rc_dev *dev, struct ir_raw_event event);
 
-       /* These two should only be used by the lirc decoder */
+       /* These two should only be used by the mce kbd decoder */
        int (*raw_register)(struct rc_dev *dev);
        int (*raw_unregister)(struct rc_dev *dev);
 };
@@ -99,17 +99,6 @@ struct ir_raw_event_ctrl {
                unsigned count;
                unsigned wanted_bits;
        } mce_kbd;
-       struct lirc_codec {
-               struct rc_dev *dev;
-               struct lirc_driver *drv;
-               int carrier_low;
-
-               ktime_t gap_start;
-               u64 gap_duration;
-               bool gap;
-               bool send_timeout_reports;
-
-       } lirc;
        struct xmp_dec {
                int state;
                unsigned count;
@@ -223,13 +212,6 @@ static inline void load_sharp_decode(void) { }
 static inline void load_mce_kbd_decode(void) { }
 #endif
 
-/* from ir-lirc-codec.c */
-#ifdef CONFIG_IR_LIRC_CODEC_MODULE
-#define load_lirc_codec()      request_module_nowait("ir-lirc-codec")
-#else
-static inline void load_lirc_codec(void) { }
-#endif
-
 /* from ir-xmp-decoder.c */
 #ifdef CONFIG_IR_XMP_DECODER_MODULE
 #define load_xmp_decode()      request_module_nowait("ir-xmp-decoder")
@@ -237,5 +219,23 @@ static inline void load_lirc_codec(void) { }
 static inline void load_xmp_decode(void) { }
 #endif
 
+#ifdef CONFIG_IR_LIRC_CODEC
+void ir_lirc_unregister(struct rc_dev *dev);
+int ir_lirc_register(struct rc_dev *dev);
+int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev);
+#else
+static inline void ir_lirc_unregister(struct rc_dev *dev) {}
+static inline int ir_lirc_register(struct rc_dev *dev) { return 0; }
+static inline int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
+                                                               { return 0; }
+#endif
+
+#ifdef CONFIG_LIRC
+int __init lirc_dev_init(void);
+void __exit lirc_dev_exit(void);
+#else
+int __init lirc_dev_init(void) { return 0; }
+void __exit lirc_dev_exit(void) {}
+#endif
 
 #endif /* _RC_CORE_PRIV */
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index b732ac6..d298be7 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -57,6 +57,9 @@ static int ir_raw_event_thread(void *data)
                retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev));
                spin_unlock_irq(&raw->lock);
 
+               if (raw->dev->lirc)
+                       ir_lirc_decode(raw->dev, ev);
+
                mutex_lock(&ir_raw_handler_lock);
                list_for_each_entry(handler, &ir_raw_handler_list, list)
                        handler->decode(raw->dev, ev);
@@ -360,7 +363,6 @@ void ir_raw_init(void)
        load_sanyo_decode();
        load_sharp_decode();
        load_mce_kbd_decode();
-       load_lirc_codec();
        load_xmp_decode();
 
        /* If needed, we may later add some init code. In this case,
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index f8c5e47..128909c 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -732,7 +732,6 @@ int rc_open(struct rc_dev *rdev)
 
        return rval;
 }
-EXPORT_SYMBOL_GPL(rc_open);
 
 static int ir_open(struct input_dev *idev)
 {
@@ -752,7 +751,6 @@ void rc_close(struct rc_dev *rdev)
                mutex_unlock(&rdev->lock);
        }
 }
-EXPORT_SYMBOL_GPL(rc_close);
 
 static void ir_close(struct input_dev *idev)
 {
@@ -1419,15 +1417,17 @@ int rc_register_device(struct rc_dev *dev)
                mutex_lock(&dev->lock);
                if (rc < 0)
                        goto out_input;
+
+               rc = ir_lirc_register(dev);
+               if (rc < 0)
+                       goto out_raw;
        }
 
        if (dev->change_protocol) {
                u64 rc_type = (1ll << rc_map->rc_type);
-               if (dev->driver_type == RC_DRIVER_IR_RAW)
-                       rc_type |= RC_BIT_LIRC;
                rc = dev->change_protocol(dev, &rc_type);
                if (rc < 0)
-                       goto out_raw;
+                       goto out_lirc;
                dev->enabled_protocols = rc_type;
        }
 
@@ -1441,6 +1441,8 @@ int rc_register_device(struct rc_dev *dev)
 
        return 0;
 
+out_lirc:
+       ir_lirc_unregister(dev);
 out_raw:
        if (dev->driver_type == RC_DRIVER_IR_RAW)
                ir_raw_event_unregister(dev);
@@ -1470,6 +1472,8 @@ void rc_unregister_device(struct rc_dev *dev)
        if (dev->driver_type == RC_DRIVER_IR_RAW)
                ir_raw_event_unregister(dev);
 
+       ir_lirc_unregister(dev);
+
        /* Freeing the table should also call the stop callback */
        ir_free_table(&dev->rc_map);
        IR_dprintk(1, "Freed keycode table\n");
@@ -1495,6 +1499,12 @@ static int __init rc_core_init(void)
                printk(KERN_ERR "rc_core: unable to register rc class\n");
                return rc;
        }
+       rc = lirc_dev_init();
+       if (rc) {
+               class_unregister(&rc_class);
+               printk(KERN_ERR "rc_core: unable to register lirc class\n");
+               return rc;
+       }
 
        led_trigger_register_simple("rc-feedback", &led_feedback);
        rc_map_register(&empty_map);
@@ -1507,6 +1517,7 @@ static void __exit rc_core_exit(void)
        class_unregister(&rc_class);
        led_trigger_unregister_simple(led_feedback);
        rc_map_unregister(&empty_map);
+       lirc_dev_exit();
 }
 
 subsys_initcall(rc_core_init);
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 2c7fbca..e3f217c 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -156,6 +156,13 @@ struct rc_dev {
        u32                             max_timeout;
        u32                             rx_resolution;
        u32                             tx_resolution;
+       /* lirc state */
+       struct lirc_driver              *lirc;
+       int                             carrier_low;
+       ktime_t                         gap_start;
+       u64                             gap_duration;
+       bool                            gap;
+       bool                            send_timeout_reports;
        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);
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to