Re: [PATCH 09/13] IR: add helper function for hardware with small o/b buffer.

2010-08-02 Thread Maxim Levitsky
On Sun, 2010-08-01 at 22:11 -0400, Andy Walls wrote: 
 On Sat, 2010-07-31 at 17:59 +0300, Maxim Levitsky wrote:
  Some ir input devices have small buffer, and interrupt the host
  each time it is full (or half full)
  
  Add a helper that automaticly handles timeouts, and also
  automaticly merges samples of same time (space-space)
  Such samples might be placed by hardware because size of
  sample in the buffer is small (a byte for example).
  
  Also remove constness from ir_dev_props, because it now contains timeout
  settings that driver might want to change
  
  Signed-off-by: Maxim Levitsky maximlevit...@gmail.com
  Acked-by: Jarod Wilson ja...@redhat.com
 
 Hi Maxim and Jarod,
 
 I've started looking at this patch, and patch 10/13, to work with them
 and build upon them.  I have some comments, below:
 
 
  ---
   drivers/media/IR/ir-core-priv.h |1 +
   drivers/media/IR/ir-keytable.c  |2 +-
   drivers/media/IR/ir-raw-event.c |   84 
  +++
   include/media/ir-core.h |   23 +-
   4 files changed, 106 insertions(+), 4 deletions(-)
  
  diff --git a/drivers/media/IR/ir-core-priv.h 
  b/drivers/media/IR/ir-core-priv.h
  index be68172..8053e3b 100644
  --- a/drivers/media/IR/ir-core-priv.h
  +++ b/drivers/media/IR/ir-core-priv.h
  @@ -41,6 +41,7 @@ struct ir_raw_event_ctrl {
   
  /* raw decoder state follows */
  struct ir_raw_event prev_ev;
  +   struct ir_raw_event this_ev;
  struct nec_dec {
  int state;
  unsigned count;
  diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
  index 94a8577..34b9c07 100644
  --- a/drivers/media/IR/ir-keytable.c
  +++ b/drivers/media/IR/ir-keytable.c
  @@ -428,7 +428,7 @@ static void ir_close(struct input_dev *input_dev)
*/
   int __ir_input_register(struct input_dev *input_dev,
const struct ir_scancode_table *rc_tab,
  - const struct ir_dev_props *props,
  + struct ir_dev_props *props,
const char *driver_name)
   {
  struct ir_input_dev *ir_dev;
  diff --git a/drivers/media/IR/ir-raw-event.c 
  b/drivers/media/IR/ir-raw-event.c
  index d0c18db..43094e7 100644
  --- a/drivers/media/IR/ir-raw-event.c
  +++ b/drivers/media/IR/ir-raw-event.c
  @@ -140,6 +140,90 @@ int ir_raw_event_store_edge(struct input_dev 
  *input_dev, enum raw_event_type typ
   EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
   
   /**
  + * ir_raw_event_store_with_filter() - pass next pulse/space to decoders 
  with some processing
  + * @input_dev: the struct input_dev device descriptor
  + * @type:  the type of the event that has occurred
  + *
  + * This routine (which may be called from an interrupt context) works
  + * in similiar manner to ir_raw_event_store_edge.
  + * This routine is intended for devices with limited internal buffer
  + * It automerges samples of same type, and handles timeouts
  + */
 
 I think this comment might need to explain the filtering being performed
 a little more explicitly, because handles timeouts wasn't enough to go
 on.
 
 From what I can tell, it performs
 
   a. space aggrregation
   b. auto idle of the receiver and some state
   c. gap measurment and gap space event generation
   d, decoder reset at the end of the gap
 
 (For my needs, c. is very useful, and a.  d. don't hurt.)
 
 What is idle supposed to do for hardware that provides interrupts?
In my case, I can program hardware not to interrupt host until it has
a sample that isn't a overflow sample
Exaplanation what overflow sample is:
Hardware stores samples in small 8 bytes buffer, and has a  flag which
half of this buffer to read.
Each sample is 8 bits, out of which 7 are timing and 8th is pulse/space.
So larger sample is sample period * 127.
If hardware wants to send larger sample, it sends this sample, and
another.
When I enable idle mode, it won't send sample with 127 within them.
Note that this is only supported on my receiver. Newer receivers don't
have that function, but rather stop sending samples on their own after
about 250 ms.



 
 Aside from asking the hardware driver to do something, idle otherwise
 appears to be used to keep track of being in a gap or not.
 Did I get that all right?
Yes of course.

 
  +int ir_raw_event_store_with_filter(struct input_dev *input_dev,
  +   struct ir_raw_event *ev)
  +{
  +   struct ir_input_dev *ir = input_get_drvdata(input_dev);
  +   struct ir_raw_event_ctrl *raw = ir-raw;
  +
  +   if (!raw || !ir-props)
  +   return -EINVAL;
  +
  +   /* Ignore spaces in idle mode */
  +   if (ir-idle  !ev-pulse)
  +   return 0;
  +   else if (ir-idle)
  +   ir_raw_event_set_idle(input_dev, 0);
  +
  +   if (!raw-this_ev.duration) {
  +   raw-this_ev = *ev;
  +   } else if (ev-pulse == raw-this_ev.pulse) {
  +   raw-this_ev.duration += ev-duration;
  +   } else {
  +  

Re: [PATCH 09/13] IR: add helper function for hardware with small o/b buffer.

2010-08-02 Thread Jarod Wilson
On Sun, Aug 01, 2010 at 10:11:01PM -0400, Andy Walls wrote:
 On Sat, 2010-07-31 at 17:59 +0300, Maxim Levitsky wrote:
...
   struct ir_input_dev {
  @@ -69,9 +81,10 @@ struct ir_input_dev {
  char*driver_name;   /* Name of the driver 
  module */
  struct ir_scancode_tablerc_tab; /* scan/key table */
  unsigned long   devno;  /* device number */
  -   const struct ir_dev_props   *props; /* Device properties */
  +   struct ir_dev_props *props; /* Device properties */
 
 So I don't think the struct ir_dev_props structure is the right place to
 be storing current operating parameters. IMO, operating parameters
 stored in the ir_dev_props are too far from the lower level driver,
 and are essentially mirroring what the low level driver should be
 tracking internally as it's own state anyway.
 
 
 So in summary, I think we need to keep the opertions in struct
 ir_dev_props simple using ,get_parameters() and .set_parameters() to
 contol the lower level driver and to fetch, retrieve, and store
 parameters.

Yeah, I neglected to consider this change the first pass through an
earlier revision. Making props modifiable on the fly does feel like we're
mixing up hardware features with hardware state, and perhaps the
on-the-fly-modifiable state bits should be stored somewhere else.

-- 
Jarod Wilson
ja...@redhat.com

--
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


Re: [PATCH 09/13] IR: add helper function for hardware with small o/b buffer.

2010-08-01 Thread Andy Walls
On Sat, 2010-07-31 at 17:59 +0300, Maxim Levitsky wrote:
 Some ir input devices have small buffer, and interrupt the host
 each time it is full (or half full)
 
 Add a helper that automaticly handles timeouts, and also
 automaticly merges samples of same time (space-space)
 Such samples might be placed by hardware because size of
 sample in the buffer is small (a byte for example).
 
 Also remove constness from ir_dev_props, because it now contains timeout
 settings that driver might want to change
 
 Signed-off-by: Maxim Levitsky maximlevit...@gmail.com
 Acked-by: Jarod Wilson ja...@redhat.com

Hi Maxim and Jarod,

I've started looking at this patch, and patch 10/13, to work with them
and build upon them.  I have some comments, below:


 ---
  drivers/media/IR/ir-core-priv.h |1 +
  drivers/media/IR/ir-keytable.c  |2 +-
  drivers/media/IR/ir-raw-event.c |   84 
 +++
  include/media/ir-core.h |   23 +-
  4 files changed, 106 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
 index be68172..8053e3b 100644
 --- a/drivers/media/IR/ir-core-priv.h
 +++ b/drivers/media/IR/ir-core-priv.h
 @@ -41,6 +41,7 @@ struct ir_raw_event_ctrl {
  
   /* raw decoder state follows */
   struct ir_raw_event prev_ev;
 + struct ir_raw_event this_ev;
   struct nec_dec {
   int state;
   unsigned count;
 diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
 index 94a8577..34b9c07 100644
 --- a/drivers/media/IR/ir-keytable.c
 +++ b/drivers/media/IR/ir-keytable.c
 @@ -428,7 +428,7 @@ static void ir_close(struct input_dev *input_dev)
   */
  int __ir_input_register(struct input_dev *input_dev,
 const struct ir_scancode_table *rc_tab,
 -   const struct ir_dev_props *props,
 +   struct ir_dev_props *props,
 const char *driver_name)
  {
   struct ir_input_dev *ir_dev;
 diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
 index d0c18db..43094e7 100644
 --- a/drivers/media/IR/ir-raw-event.c
 +++ b/drivers/media/IR/ir-raw-event.c
 @@ -140,6 +140,90 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, 
 enum raw_event_type typ
  EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
  
  /**
 + * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with 
 some processing
 + * @input_dev:   the struct input_dev device descriptor
 + * @type:the type of the event that has occurred
 + *
 + * This routine (which may be called from an interrupt context) works
 + * in similiar manner to ir_raw_event_store_edge.
 + * This routine is intended for devices with limited internal buffer
 + * It automerges samples of same type, and handles timeouts
 + */

I think this comment might need to explain the filtering being performed
a little more explicitly, because handles timeouts wasn't enough to go
on.

From what I can tell, it performs

a. space aggrregation
b. auto idle of the receiver and some state
c. gap measurment and gap space event generation
d, decoder reset at the end of the gap

(For my needs, c. is very useful, and a.  d. don't hurt.)

What is idle supposed to do for hardware that provides interrupts?

Aside from asking the hardware driver to do something, idle otherwise
appears to be used to keep track of being in a gap or not.
Did I get that all right?

 +int ir_raw_event_store_with_filter(struct input_dev *input_dev,
 + struct ir_raw_event *ev)
 +{
 + struct ir_input_dev *ir = input_get_drvdata(input_dev);
 + struct ir_raw_event_ctrl *raw = ir-raw;
 +
 + if (!raw || !ir-props)
 + return -EINVAL;
 +
 + /* Ignore spaces in idle mode */
 + if (ir-idle  !ev-pulse)
 + return 0;
 + else if (ir-idle)
 + ir_raw_event_set_idle(input_dev, 0);
 +
 + if (!raw-this_ev.duration) {
 + raw-this_ev = *ev;
 + } else if (ev-pulse == raw-this_ev.pulse) {
 + raw-this_ev.duration += ev-duration;
 + } else {
 + ir_raw_event_store(input_dev, raw-this_ev);
 + raw-this_ev = *ev;
 + }
 +
 + /* Enter idle mode if nessesary */
 + if (!ev-pulse  ir-props-timeout 
 + raw-this_ev.duration = ir-props-timeout)
 + ir_raw_event_set_idle(input_dev, 1);
 + return 0;
 +}
 +EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
 +
 +void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
 +{
 + struct ir_input_dev *ir = input_get_drvdata(input_dev);
 + struct ir_raw_event_ctrl *raw = ir-raw;
 + ktime_t now;
 + u64 delta;
 +
 + if (!ir-props)
 + return;
 +
 + if (!ir-raw)
 + goto out;
 +
 + if (idle) {
 + IR_dprintk(2, enter idle mode\n);
 + raw-last_event = 

[PATCH 09/13] IR: add helper function for hardware with small o/b buffer.

2010-07-31 Thread Maxim Levitsky
Some ir input devices have small buffer, and interrupt the host
each time it is full (or half full)

Add a helper that automaticly handles timeouts, and also
automaticly merges samples of same time (space-space)
Such samples might be placed by hardware because size of
sample in the buffer is small (a byte for example).

Also remove constness from ir_dev_props, because it now contains timeout
settings that driver might want to change

Signed-off-by: Maxim Levitsky maximlevit...@gmail.com
Acked-by: Jarod Wilson ja...@redhat.com
---
 drivers/media/IR/ir-core-priv.h |1 +
 drivers/media/IR/ir-keytable.c  |2 +-
 drivers/media/IR/ir-raw-event.c |   84 +++
 include/media/ir-core.h |   23 +-
 4 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index be68172..8053e3b 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -41,6 +41,7 @@ struct ir_raw_event_ctrl {
 
/* raw decoder state follows */
struct ir_raw_event prev_ev;
+   struct ir_raw_event this_ev;
struct nec_dec {
int state;
unsigned count;
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index 94a8577..34b9c07 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -428,7 +428,7 @@ static void ir_close(struct input_dev *input_dev)
  */
 int __ir_input_register(struct input_dev *input_dev,
  const struct ir_scancode_table *rc_tab,
- const struct ir_dev_props *props,
+ struct ir_dev_props *props,
  const char *driver_name)
 {
struct ir_input_dev *ir_dev;
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index d0c18db..43094e7 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -140,6 +140,90 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, 
enum raw_event_type typ
 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
 
 /**
+ * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with 
some processing
+ * @input_dev: the struct input_dev device descriptor
+ * @type:  the type of the event that has occurred
+ *
+ * This routine (which may be called from an interrupt context) works
+ * in similiar manner to ir_raw_event_store_edge.
+ * This routine is intended for devices with limited internal buffer
+ * It automerges samples of same type, and handles timeouts
+ */
+int ir_raw_event_store_with_filter(struct input_dev *input_dev,
+   struct ir_raw_event *ev)
+{
+   struct ir_input_dev *ir = input_get_drvdata(input_dev);
+   struct ir_raw_event_ctrl *raw = ir-raw;
+
+   if (!raw || !ir-props)
+   return -EINVAL;
+
+   /* Ignore spaces in idle mode */
+   if (ir-idle  !ev-pulse)
+   return 0;
+   else if (ir-idle)
+   ir_raw_event_set_idle(input_dev, 0);
+
+   if (!raw-this_ev.duration) {
+   raw-this_ev = *ev;
+   } else if (ev-pulse == raw-this_ev.pulse) {
+   raw-this_ev.duration += ev-duration;
+   } else {
+   ir_raw_event_store(input_dev, raw-this_ev);
+   raw-this_ev = *ev;
+   }
+
+   /* Enter idle mode if nessesary */
+   if (!ev-pulse  ir-props-timeout 
+   raw-this_ev.duration = ir-props-timeout)
+   ir_raw_event_set_idle(input_dev, 1);
+   return 0;
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
+
+void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
+{
+   struct ir_input_dev *ir = input_get_drvdata(input_dev);
+   struct ir_raw_event_ctrl *raw = ir-raw;
+   ktime_t now;
+   u64 delta;
+
+   if (!ir-props)
+   return;
+
+   if (!ir-raw)
+   goto out;
+
+   if (idle) {
+   IR_dprintk(2, enter idle mode\n);
+   raw-last_event = ktime_get();
+   } else {
+   IR_dprintk(2, exit idle mode\n);
+
+   now = ktime_get();
+   delta = ktime_to_ns(ktime_sub(now, ir-raw-last_event));
+
+   WARN_ON(raw-this_ev.pulse);
+
+   raw-this_ev.duration =
+   min(raw-this_ev.duration + delta,
+   (u64)IR_MAX_DURATION);
+
+   ir_raw_event_store(input_dev, raw-this_ev);
+
+   if (raw-this_ev.duration == IR_MAX_DURATION)
+   ir_raw_event_reset(input_dev);
+
+   raw-this_ev.duration = 0;
+   }
+out:
+   if (ir-props-s_idle)
+   ir-props-s_idle(ir-props-priv, idle);
+   ir-idle = idle;
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
+
+/**
  * ir_raw_event_handle() - schedules the decoding of stored ir data
  * @input_dev: the 

[PATCH 09/13] IR: add helper function for hardware with small o/b buffer.

2010-07-30 Thread Maxim Levitsky
Some ir input devices have small buffer, and interrupt the host
each time it is full (or half full)

Add a helper that automaticly handles timeouts, and also
automaticly merges samples of same time (space-space)
Such samples might be placed by hardware because size of
sample in the buffer is small (a byte for example).

Also remove constness from ir_dev_props, because it now contains timeout
settings that driver might want to change

Signed-off-by: Maxim Levitsky maximlevit...@gmail.com
---
 drivers/media/IR/ir-core-priv.h |1 +
 drivers/media/IR/ir-keytable.c  |2 +-
 drivers/media/IR/ir-raw-event.c |   84 +++
 include/media/ir-core.h |   23 +-
 4 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index e9c3cce..30ff52c 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -41,6 +41,7 @@ struct ir_raw_event_ctrl {
 
/* raw decoder state follows */
struct ir_raw_event prev_ev;
+   struct ir_raw_event this_ev;
struct nec_dec {
int state;
unsigned count;
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index 94a8577..34b9c07 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -428,7 +428,7 @@ static void ir_close(struct input_dev *input_dev)
  */
 int __ir_input_register(struct input_dev *input_dev,
  const struct ir_scancode_table *rc_tab,
- const struct ir_dev_props *props,
+ struct ir_dev_props *props,
  const char *driver_name)
 {
struct ir_input_dev *ir_dev;
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index d0c18db..43094e7 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -140,6 +140,90 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, 
enum raw_event_type typ
 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
 
 /**
+ * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with 
some processing
+ * @input_dev: the struct input_dev device descriptor
+ * @type:  the type of the event that has occurred
+ *
+ * This routine (which may be called from an interrupt context) works
+ * in similiar manner to ir_raw_event_store_edge.
+ * This routine is intended for devices with limited internal buffer
+ * It automerges samples of same type, and handles timeouts
+ */
+int ir_raw_event_store_with_filter(struct input_dev *input_dev,
+   struct ir_raw_event *ev)
+{
+   struct ir_input_dev *ir = input_get_drvdata(input_dev);
+   struct ir_raw_event_ctrl *raw = ir-raw;
+
+   if (!raw || !ir-props)
+   return -EINVAL;
+
+   /* Ignore spaces in idle mode */
+   if (ir-idle  !ev-pulse)
+   return 0;
+   else if (ir-idle)
+   ir_raw_event_set_idle(input_dev, 0);
+
+   if (!raw-this_ev.duration) {
+   raw-this_ev = *ev;
+   } else if (ev-pulse == raw-this_ev.pulse) {
+   raw-this_ev.duration += ev-duration;
+   } else {
+   ir_raw_event_store(input_dev, raw-this_ev);
+   raw-this_ev = *ev;
+   }
+
+   /* Enter idle mode if nessesary */
+   if (!ev-pulse  ir-props-timeout 
+   raw-this_ev.duration = ir-props-timeout)
+   ir_raw_event_set_idle(input_dev, 1);
+   return 0;
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
+
+void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
+{
+   struct ir_input_dev *ir = input_get_drvdata(input_dev);
+   struct ir_raw_event_ctrl *raw = ir-raw;
+   ktime_t now;
+   u64 delta;
+
+   if (!ir-props)
+   return;
+
+   if (!ir-raw)
+   goto out;
+
+   if (idle) {
+   IR_dprintk(2, enter idle mode\n);
+   raw-last_event = ktime_get();
+   } else {
+   IR_dprintk(2, exit idle mode\n);
+
+   now = ktime_get();
+   delta = ktime_to_ns(ktime_sub(now, ir-raw-last_event));
+
+   WARN_ON(raw-this_ev.pulse);
+
+   raw-this_ev.duration =
+   min(raw-this_ev.duration + delta,
+   (u64)IR_MAX_DURATION);
+
+   ir_raw_event_store(input_dev, raw-this_ev);
+
+   if (raw-this_ev.duration == IR_MAX_DURATION)
+   ir_raw_event_reset(input_dev);
+
+   raw-this_ev.duration = 0;
+   }
+out:
+   if (ir-props-s_idle)
+   ir-props-s_idle(ir-props-priv, idle);
+   ir-idle = idle;
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
+
+/**
  * ir_raw_event_handle() - schedules the decoding of stored ir data
  * @input_dev: the struct input_dev device descriptor
  *

[PATCH 09/13] IR: add helper function for hardware with small o/b buffer.

2010-07-29 Thread Maxim Levitsky
Some ir input devices have small buffer, and interrupt the host
each time it is full (or half full)

Add a helper that automaticly handles timeouts, and also
automaticly merges samples of same time (space-space)
Such samples might be placed by hardware because size of
sample in the buffer is small (a byte for example).

Also remove constness from ir_dev_props, because it now contains timeout
settings that driver might want to change

Signed-off-by: Maxim Levitsky maximlevit...@gmail.com
---
 drivers/media/IR/ir-core-priv.h |1 +
 drivers/media/IR/ir-keytable.c  |2 +-
 drivers/media/IR/ir-raw-event.c |   84 +++
 include/media/ir-core.h |   23 +-
 4 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index fe84374..841b76c 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -41,6 +41,7 @@ struct ir_raw_event_ctrl {
 
/* raw decoder state follows */
struct ir_raw_event prev_ev;
+   struct ir_raw_event this_ev;
struct nec_dec {
int state;
unsigned count;
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index 94a8577..34b9c07 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -428,7 +428,7 @@ static void ir_close(struct input_dev *input_dev)
  */
 int __ir_input_register(struct input_dev *input_dev,
  const struct ir_scancode_table *rc_tab,
- const struct ir_dev_props *props,
+ struct ir_dev_props *props,
  const char *driver_name)
 {
struct ir_input_dev *ir_dev;
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 4098748..5a6f8ce 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -132,6 +132,90 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, 
enum raw_event_type typ
 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
 
 /**
+ * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with 
some processing
+ * @input_dev: the struct input_dev device descriptor
+ * @type:  the type of the event that has occurred
+ *
+ * This routine (which may be called from an interrupt context) works
+ * in similiar manner to ir_raw_event_store_edge.
+ * This routine is intended for devices with limited internal buffer
+ * It automerges samples of same type, and handles timeouts
+ */
+int ir_raw_event_store_with_filter(struct input_dev *input_dev,
+   struct ir_raw_event *ev)
+{
+   struct ir_input_dev *ir = input_get_drvdata(input_dev);
+   struct ir_raw_event_ctrl *raw = ir-raw;
+
+   if (!raw || !ir-props)
+   return -EINVAL;
+
+   /* Ignore spaces in idle mode */
+   if (ir-idle  !ev-pulse)
+   return 0;
+   else if (ir-idle)
+   ir_raw_event_set_idle(input_dev, 0);
+
+   if (!raw-this_ev.duration) {
+   raw-this_ev = *ev;
+   } else if (ev-pulse == raw-this_ev.pulse) {
+   raw-this_ev.duration += ev-duration;
+   } else {
+   ir_raw_event_store(input_dev, raw-this_ev);
+   raw-this_ev = *ev;
+   }
+
+   /* Enter idle mode if nessesary */
+   if (!ev-pulse  ir-props-timeout 
+   raw-this_ev.duration = ir-props-timeout)
+   ir_raw_event_set_idle(input_dev, 1);
+   return 0;
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
+
+void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
+{
+   struct ir_input_dev *ir = input_get_drvdata(input_dev);
+   struct ir_raw_event_ctrl *raw = ir-raw;
+   ktime_t now;
+   u64 delta;
+
+   if (!ir-props)
+   return;
+
+   if (!ir-raw)
+   goto out;
+
+   if (idle) {
+   IR_dprintk(2, enter idle mode\n);
+   raw-last_event = ktime_get();
+   } else {
+   IR_dprintk(2, exit idle mode\n);
+
+   now = ktime_get();
+   delta = ktime_to_ns(ktime_sub(now, ir-raw-last_event));
+
+   WARN_ON(raw-this_ev.pulse);
+
+   raw-this_ev.duration =
+   min(raw-this_ev.duration + delta,
+   (u64)IR_MAX_DURATION);
+
+   ir_raw_event_store(input_dev, raw-this_ev);
+
+   if (raw-this_ev.duration == IR_MAX_DURATION)
+   ir_raw_event_reset(input_dev);
+
+   raw-this_ev.duration = 0;
+   }
+out:
+   if (ir-props-s_idle)
+   ir-props-s_idle(ir-props-priv, idle);
+   ir-idle = idle;
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
+
+/**
  * ir_raw_event_handle() - schedules the decoding of stored ir data
  * @input_dev: the struct input_dev device descriptor
  *