Merge branches 'msm-fixes' and 'msm-video' of git://codeaurora.org/quic/kernel/dwalke...
[pandora-kernel.git] / drivers / media / IR / streamzap.c
index 058e29f..548381c 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/input.h>
 #include <media/ir-core.h>
 
-#define DRIVER_VERSION "1.60"
+#define DRIVER_VERSION "1.61"
 #define DRIVER_NAME    "streamzap"
 #define DRIVER_DESC    "Streamzap Remote Control driver"
 
@@ -61,14 +61,21 @@ static struct usb_device_id streamzap_table[] = {
 
 MODULE_DEVICE_TABLE(usb, streamzap_table);
 
-#define STREAMZAP_PULSE_MASK 0xf0
-#define STREAMZAP_SPACE_MASK 0x0f
-#define STREAMZAP_TIMEOUT    0xff
-#define STREAMZAP_RESOLUTION 256
+#define SZ_PULSE_MASK 0xf0
+#define SZ_SPACE_MASK 0x0f
+#define SZ_TIMEOUT    0xff
+#define SZ_RESOLUTION 256
 
 /* number of samples buffered */
 #define SZ_BUF_LEN 128
 
+/* from ir-rc5-sz-decoder.c */
+#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
+#define load_rc5_sz_decode()    request_module("ir-rc5-sz-decoder")
+#else
+#define load_rc5_sz_decode()    0
+#endif
+
 enum StreamzapDecoderState {
        PulseSpace,
        FullPulse,
@@ -81,7 +88,6 @@ struct streamzap_ir {
 
        /* ir-core */
        struct ir_dev_props *props;
-       struct ir_raw_event rawir;
 
        /* core device info */
        struct device *dev;
@@ -98,17 +104,6 @@ struct streamzap_ir {
        dma_addr_t              dma_in;
        unsigned int            buf_in_len;
 
-       /* timer used to support delay buffering */
-       struct timer_list       delay_timer;
-       bool                    timer_running;
-       spinlock_t              timer_lock;
-       struct timer_list       flush_timer;
-       bool                    flush;
-
-       /* delay buffer */
-       struct kfifo fifo;
-       bool fifo_initialized;
-
        /* track what state we're in */
        enum StreamzapDecoderState decoder_state;
        /* tracks whether we are currently receiving some signal */
@@ -118,7 +113,7 @@ struct streamzap_ir {
        /* start time of signal; necessary for gap tracking */
        struct timeval          signal_last;
        struct timeval          signal_start;
-       /* bool                 timeout_enabled; */
+       bool                    timeout_enabled;
 
        char                    name[128];
        char                    phys[64];
@@ -143,122 +138,16 @@ static struct usb_driver streamzap_driver = {
        .id_table =     streamzap_table,
 };
 
-static void streamzap_stop_timer(struct streamzap_ir *sz)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&sz->timer_lock, flags);
-       if (sz->timer_running) {
-               sz->timer_running = false;
-               spin_unlock_irqrestore(&sz->timer_lock, flags);
-               del_timer_sync(&sz->delay_timer);
-       } else {
-               spin_unlock_irqrestore(&sz->timer_lock, flags);
-       }
-}
-
-static void streamzap_flush_timeout(unsigned long arg)
-{
-       struct streamzap_ir *sz = (struct streamzap_ir *)arg;
-
-       dev_info(sz->dev, "%s: callback firing\n", __func__);
-
-       /* finally start accepting data */
-       sz->flush = false;
-}
-
-static void streamzap_delay_timeout(unsigned long arg)
-{
-       struct streamzap_ir *sz = (struct streamzap_ir *)arg;
-       struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
-       unsigned long flags;
-       int len, ret;
-       static unsigned long delay;
-       bool wake = false;
-
-       /* deliver data every 10 ms */
-       delay = msecs_to_jiffies(10);
-
-       spin_lock_irqsave(&sz->timer_lock, flags);
-
-       if (kfifo_len(&sz->fifo) > 0) {
-               ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
-               if (ret != sizeof(rawir))
-                       dev_err(sz->dev, "Problem w/kfifo_out...\n");
-               ir_raw_event_store(sz->idev, &rawir);
-               wake = true;
-       }
-
-       len = kfifo_len(&sz->fifo);
-       if (len > 0) {
-               while ((len < SZ_BUF_LEN / 2) &&
-                      (len < SZ_BUF_LEN * sizeof(int))) {
-                       ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
-                       if (ret != sizeof(rawir))
-                               dev_err(sz->dev, "Problem w/kfifo_out...\n");
-                       ir_raw_event_store(sz->idev, &rawir);
-                       wake = true;
-                       len = kfifo_len(&sz->fifo);
-               }
-               if (sz->timer_running)
-                       mod_timer(&sz->delay_timer, jiffies + delay);
-
-       } else {
-               sz->timer_running = false;
-       }
-
-       if (wake)
-               ir_raw_event_handle(sz->idev);
-
-       spin_unlock_irqrestore(&sz->timer_lock, flags);
-}
-
-static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
+static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
 {
-       struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
-       bool wake = false;
-       int ret;
-
-       while (kfifo_len(&sz->fifo) > 0) {
-               ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
-               if (ret != sizeof(rawir))
-                       dev_err(sz->dev, "Problem w/kfifo_out...\n");
-               ir_raw_event_store(sz->idev, &rawir);
-               wake = true;
-       }
-
-       if (wake)
-               ir_raw_event_handle(sz->idev);
-}
-
-static void sz_push(struct streamzap_ir *sz)
-{
-       struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&sz->timer_lock, flags);
-       if (kfifo_len(&sz->fifo) >= sizeof(int) * SZ_BUF_LEN) {
-               ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
-               if (ret != sizeof(rawir))
-                       dev_err(sz->dev, "Problem w/kfifo_out...\n");
-               ir_raw_event_store(sz->idev, &rawir);
-       }
-
-       kfifo_in(&sz->fifo, &sz->rawir, sizeof(rawir));
-
-       if (!sz->timer_running) {
-               sz->delay_timer.expires = jiffies + (HZ / 10);
-               add_timer(&sz->delay_timer);
-               sz->timer_running = true;
-       }
-
-       spin_unlock_irqrestore(&sz->timer_lock, flags);
+       ir_raw_event_store(sz->idev, &rawir);
 }
 
 static void sz_push_full_pulse(struct streamzap_ir *sz,
                               unsigned char value)
 {
+       DEFINE_IR_RAW_EVENT(rawir);
+
        if (sz->idle) {
                long deltv;
 
@@ -266,57 +155,59 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
                do_gettimeofday(&sz->signal_start);
 
                deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
-               sz->rawir.pulse = false;
+               rawir.pulse = false;
                if (deltv > 15) {
                        /* really long time */
-                       sz->rawir.duration = IR_MAX_DURATION;
+                       rawir.duration = IR_MAX_DURATION;
                } else {
-                       sz->rawir.duration = (int)(deltv * 1000000 +
+                       rawir.duration = (int)(deltv * 1000000 +
                                sz->signal_start.tv_usec -
                                sz->signal_last.tv_usec);
-                       sz->rawir.duration -= sz->sum;
-                       sz->rawir.duration *= 1000;
-                       sz->rawir.duration &= IR_MAX_DURATION;
+                       rawir.duration -= sz->sum;
+                       rawir.duration *= 1000;
+                       rawir.duration &= IR_MAX_DURATION;
                }
-               dev_dbg(sz->dev, "ls %u\n", sz->rawir.duration);
-               sz_push(sz);
+               dev_dbg(sz->dev, "ls %u\n", rawir.duration);
+               sz_push(sz, rawir);
 
-               sz->idle = 0;
+               sz->idle = false;
                sz->sum = 0;
        }
 
-       sz->rawir.pulse = true;
-       sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
-       sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
-       sz->sum += sz->rawir.duration;
-       sz->rawir.duration *= 1000;
-       sz->rawir.duration &= IR_MAX_DURATION;
-       dev_dbg(sz->dev, "p %u\n", sz->rawir.duration);
-       sz_push(sz);
+       rawir.pulse = true;
+       rawir.duration = ((int) value) * SZ_RESOLUTION;
+       rawir.duration += SZ_RESOLUTION / 2;
+       sz->sum += rawir.duration;
+       rawir.duration *= 1000;
+       rawir.duration &= IR_MAX_DURATION;
+       dev_dbg(sz->dev, "p %u\n", rawir.duration);
+       sz_push(sz, rawir);
 }
 
 static void sz_push_half_pulse(struct streamzap_ir *sz,
                               unsigned char value)
 {
-       sz_push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK) >> 4);
+       sz_push_full_pulse(sz, (value & SZ_PULSE_MASK) >> 4);
 }
 
 static void sz_push_full_space(struct streamzap_ir *sz,
                               unsigned char value)
 {
-       sz->rawir.pulse = false;
-       sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
-       sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
-       sz->sum += sz->rawir.duration;
-       sz->rawir.duration *= 1000;
-       dev_dbg(sz->dev, "s %u\n", sz->rawir.duration);
-       sz_push(sz);
+       DEFINE_IR_RAW_EVENT(rawir);
+
+       rawir.pulse = false;
+       rawir.duration = ((int) value) * SZ_RESOLUTION;
+       rawir.duration += SZ_RESOLUTION / 2;
+       sz->sum += rawir.duration;
+       rawir.duration *= 1000;
+       dev_dbg(sz->dev, "s %u\n", rawir.duration);
+       sz_push(sz, rawir);
 }
 
 static void sz_push_half_space(struct streamzap_ir *sz,
                               unsigned long value)
 {
-       sz_push_full_space(sz, value & STREAMZAP_SPACE_MASK);
+       sz_push_full_space(sz, value & SZ_SPACE_MASK);
 }
 
 /**
@@ -330,10 +221,8 @@ static void streamzap_callback(struct urb *urb)
        struct streamzap_ir *sz;
        unsigned int i;
        int len;
-       #if 0
-       static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) &
+       static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
                                IR_MAX_DURATION) | 0x03000000);
-       #endif
 
        if (!urb)
                return;
@@ -356,57 +245,53 @@ static void streamzap_callback(struct urb *urb)
        }
 
        dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
-       if (!sz->flush) {
-               for (i = 0; i < urb->actual_length; i++) {
-                       dev_dbg(sz->dev, "%d: %x\n", i,
-                               (unsigned char)sz->buf_in[i]);
-                       switch (sz->decoder_state) {
-                       case PulseSpace:
-                               if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
-                                   STREAMZAP_PULSE_MASK) {
-                                       sz->decoder_state = FullPulse;
-                                       continue;
-                               } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
-                                          == STREAMZAP_SPACE_MASK) {
-                                       sz_push_half_pulse(sz, sz->buf_in[i]);
-                                       sz->decoder_state = FullSpace;
-                                       continue;
-                               } else {
-                                       sz_push_half_pulse(sz, sz->buf_in[i]);
-                                       sz_push_half_space(sz, sz->buf_in[i]);
-                               }
-                               break;
-                       case FullPulse:
-                               sz_push_full_pulse(sz, sz->buf_in[i]);
-                               sz->decoder_state = IgnorePulse;
-                               break;
-                       case FullSpace:
-                               if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
-                                       sz->idle = 1;
-                                       streamzap_stop_timer(sz);
-                                       #if 0
-                                       if (sz->timeout_enabled) {
-                                               sz->rawir.pulse = false;
-                                               sz->rawir.duration = timeout;
-                                               sz->rawir.duration *= 1000;
-                                               sz_push(sz);
-                                       }
-                                       #endif
-                                       streamzap_flush_delay_buffer(sz);
-                               } else
-                                       sz_push_full_space(sz, sz->buf_in[i]);
-                               sz->decoder_state = PulseSpace;
-                               break;
-                       case IgnorePulse:
-                               if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) ==
-                                   STREAMZAP_SPACE_MASK) {
-                                       sz->decoder_state = FullSpace;
-                                       continue;
-                               }
+       for (i = 0; i < len; i++) {
+               dev_dbg(sz->dev, "sz idx %d: %x\n",
+                       i, (unsigned char)sz->buf_in[i]);
+               switch (sz->decoder_state) {
+               case PulseSpace:
+                       if ((sz->buf_in[i] & SZ_PULSE_MASK) ==
+                               SZ_PULSE_MASK) {
+                               sz->decoder_state = FullPulse;
+                               continue;
+                       } else if ((sz->buf_in[i] & SZ_SPACE_MASK)
+                                       == SZ_SPACE_MASK) {
+                               sz_push_half_pulse(sz, sz->buf_in[i]);
+                               sz->decoder_state = FullSpace;
+                               continue;
+                       } else {
+                               sz_push_half_pulse(sz, sz->buf_in[i]);
                                sz_push_half_space(sz, sz->buf_in[i]);
-                               sz->decoder_state = PulseSpace;
-                               break;
                        }
+                       break;
+               case FullPulse:
+                       sz_push_full_pulse(sz, sz->buf_in[i]);
+                       sz->decoder_state = IgnorePulse;
+                       break;
+               case FullSpace:
+                       if (sz->buf_in[i] == SZ_TIMEOUT) {
+                               DEFINE_IR_RAW_EVENT(rawir);
+
+                               rawir.pulse = false;
+                               rawir.duration = timeout;
+                               sz->idle = true;
+                               if (sz->timeout_enabled)
+                                       sz_push(sz, rawir);
+                               ir_raw_event_handle(sz->idev);
+                       } else {
+                               sz_push_full_space(sz, sz->buf_in[i]);
+                       }
+                       sz->decoder_state = PulseSpace;
+                       break;
+               case IgnorePulse:
+                       if ((sz->buf_in[i] & SZ_SPACE_MASK) ==
+                               SZ_SPACE_MASK) {
+                               sz->decoder_state = FullSpace;
+                               continue;
+                       }
+                       sz_push_half_space(sz, sz->buf_in[i]);
+                       sz->decoder_state = PulseSpace;
+                       break;
                }
        }
 
@@ -446,12 +331,11 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
 
        props->priv = sz;
        props->driver_type = RC_DRIVER_IR_RAW;
-       /* FIXME: not sure about supported protocols, check on this */
-       props->allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6;
+       props->allowed_protos = IR_TYPE_ALL;
 
        sz->props = props;
 
-       ret = ir_input_register(idev, RC_MAP_RC5_STREAMZAP, props, DRIVER_NAME);
+       ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
        if (ret < 0) {
                dev_err(dev, "remote input device register failed\n");
                goto irdev_failed;
@@ -467,29 +351,6 @@ idev_alloc_failed:
        return NULL;
 }
 
-static int streamzap_delay_buf_init(struct streamzap_ir *sz)
-{
-       int ret;
-
-       ret = kfifo_alloc(&sz->fifo, sizeof(int) * SZ_BUF_LEN,
-                         GFP_KERNEL);
-       if (ret == 0)
-               sz->fifo_initialized = 1;
-
-       return ret;
-}
-
-static void streamzap_start_flush_timer(struct streamzap_ir *sz)
-{
-       sz->flush_timer.expires = jiffies + HZ;
-       sz->flush = true;
-       add_timer(&sz->flush_timer);
-
-       sz->urb_in->dev = sz->usbdev;
-       if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
-               dev_err(sz->dev, "urb submit failed\n");
-}
-
 /**
  *     streamzap_probe
  *
@@ -575,35 +436,21 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
                snprintf(name + strlen(name), sizeof(name) - strlen(name),
                         " %s", buf);
 
-       retval = streamzap_delay_buf_init(sz);
-       if (retval) {
-               dev_err(&intf->dev, "%s: delay buffer init failed\n", __func__);
-               goto free_urb_in;
-       }
-
        sz->idev = streamzap_init_input_dev(sz);
        if (!sz->idev)
                goto input_dev_fail;
 
        sz->idle = true;
        sz->decoder_state = PulseSpace;
+       /* FIXME: don't yet have a way to set this */
+       sz->timeout_enabled = true;
        #if 0
        /* not yet supported, depends on patches from maxim */
        /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
-       sz->timeout_enabled = false;
-       sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
-       sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
+       sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
+       sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
        #endif
 
-       init_timer(&sz->delay_timer);
-       sz->delay_timer.function = streamzap_delay_timeout;
-       sz->delay_timer.data = (unsigned long)sz;
-       spin_lock_init(&sz->timer_lock);
-
-       init_timer(&sz->flush_timer);
-       sz->flush_timer.function = streamzap_flush_timeout;
-       sz->flush_timer.data = (unsigned long)sz;
-
        do_gettimeofday(&sz->signal_start);
 
        /* Complete final initialisations */
@@ -615,16 +462,18 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
 
        usb_set_intfdata(intf, sz);
 
-       streamzap_start_flush_timer(sz);
+       if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
+               dev_err(sz->dev, "urb submit failed\n");
 
        dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
                 usbdev->bus->busnum, usbdev->devnum);
 
+       /* Load the streamzap not-quite-rc5 decoder too */
+       load_rc5_sz_decode();
+
        return 0;
 
 input_dev_fail:
-       kfifo_free(&sz->fifo);
-free_urb_in:
        usb_free_urb(sz->urb_in);
 free_buf_in:
        usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
@@ -654,13 +503,6 @@ static void streamzap_disconnect(struct usb_interface *interface)
        if (!sz)
                return;
 
-       if (sz->flush) {
-               sz->flush = false;
-               del_timer_sync(&sz->flush_timer);
-       }
-
-       streamzap_stop_timer(sz);
-
        sz->usbdev = NULL;
        ir_input_unregister(sz->idev);
        usb_kill_urb(sz->urb_in);
@@ -674,13 +516,6 @@ static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
 {
        struct streamzap_ir *sz = usb_get_intfdata(intf);
 
-       if (sz->flush) {
-               sz->flush = false;
-               del_timer_sync(&sz->flush_timer);
-       }
-
-       streamzap_stop_timer(sz);
-
        usb_kill_urb(sz->urb_in);
 
        return 0;
@@ -690,13 +525,6 @@ static int streamzap_resume(struct usb_interface *intf)
 {
        struct streamzap_ir *sz = usb_get_intfdata(intf);
 
-       if (sz->fifo_initialized)
-               kfifo_reset(&sz->fifo);
-
-       sz->flush_timer.expires = jiffies + HZ;
-       sz->flush = true;
-       add_timer(&sz->flush_timer);
-
        if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
                dev_err(sz->dev, "Error sumbiting urb\n");
                return -EIO;