aboutsummaryrefslogtreecommitdiffstats
path: root/include/media
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2010-04-08 12:10:00 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-19 11:57:03 -0400
commit724e2495502a98aaa3f93c404472a991da8ff857 (patch)
treedfdc90b4408fa95f7757b1c6e5b36c2789da0df2 /include/media
parentd22e546ea18ee66c255af906f2714d3ee82d4b42 (diff)
V4L/DVB: Teach drivers/media/IR/ir-raw-event.c to use durations
drivers/media/IR/ir-raw-event.c is currently written with the assumption that all "raw" hardware will generate events only on state change (i.e. when a pulse or space starts). However, some hardware (like mceusb, probably the most popular IR receiver out there) only generates duration data (and that data is buffered so using any kind of timing on the data is futile). Furthermore, using signed int's to represent pulse/space durations is a well-known approach when writing ir decoders. With this patch: - s64 int's are used to represent pulse/space durations in ns - a workqueue is used to decode the ir protocols outside of interrupt context - #defines are added to make decoders clearer - decoder reset is implemented by passing a zero duration to the kfifo queue and decoders are updated accordingly Signed-off-by: David Härdeman <david@hardeman.nu> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'include/media')
-rw-r--r--include/media/ir-core.h47
1 files changed, 36 insertions, 11 deletions
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index e9fa94fe2ef5..e9a0cbf67ff6 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -65,14 +65,12 @@ struct ir_dev_props {
65 void (*close)(void *priv); 65 void (*close)(void *priv);
66}; 66};
67 67
68struct ir_raw_event {
69 struct timespec delta; /* Time spent before event */
70 enum raw_event_type type; /* event type */
71};
72
73struct ir_raw_event_ctrl { 68struct ir_raw_event_ctrl {
74 struct kfifo kfifo; /* fifo for the pulse/space events */ 69 struct work_struct rx_work; /* for the rx decoding workqueue */
75 struct timespec last_event; /* when last event occurred */ 70 struct kfifo kfifo; /* fifo for the pulse/space durations */
71 ktime_t last_event; /* when last event occurred */
72 enum raw_event_type last_type; /* last event type */
73 struct input_dev *input_dev; /* pointer to the parent input_dev */
76}; 74};
77 75
78struct ir_input_dev { 76struct ir_input_dev {
@@ -97,8 +95,7 @@ struct ir_input_dev {
97struct ir_raw_handler { 95struct ir_raw_handler {
98 struct list_head list; 96 struct list_head list;
99 97
100 int (*decode)(struct input_dev *input_dev, 98 int (*decode)(struct input_dev *input_dev, s64 duration);
101 struct ir_raw_event *ev);
102 int (*raw_register)(struct input_dev *input_dev); 99 int (*raw_register)(struct input_dev *input_dev);
103 int (*raw_unregister)(struct input_dev *input_dev); 100 int (*raw_unregister)(struct input_dev *input_dev);
104}; 101};
@@ -154,8 +151,14 @@ void ir_unregister_class(struct input_dev *input_dev);
154/* Routines from ir-raw-event.c */ 151/* Routines from ir-raw-event.c */
155int ir_raw_event_register(struct input_dev *input_dev); 152int ir_raw_event_register(struct input_dev *input_dev);
156void ir_raw_event_unregister(struct input_dev *input_dev); 153void ir_raw_event_unregister(struct input_dev *input_dev);
157int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type); 154void ir_raw_event_handle(struct input_dev *input_dev);
158int ir_raw_event_handle(struct input_dev *input_dev); 155int ir_raw_event_store(struct input_dev *input_dev, s64 duration);
156int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
157static inline void ir_raw_event_reset(struct input_dev *input_dev)
158{
159 ir_raw_event_store(input_dev, 0);
160 ir_raw_event_handle(input_dev);
161}
159int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); 162int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
160void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); 163void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
161void ir_raw_init(void); 164void ir_raw_init(void);
@@ -174,4 +177,26 @@ void ir_raw_init(void);
174#define load_rc5_decode() 0 177#define load_rc5_decode() 0
175#endif 178#endif
176 179
180/* macros for ir decoders */
181#define PULSE(units) ((units))
182#define SPACE(units) (-(units))
183#define IS_RESET(duration) ((duration) == 0)
184#define IS_PULSE(duration) ((duration) > 0)
185#define IS_SPACE(duration) ((duration) < 0)
186#define DURATION(duration) (abs((duration)))
187#define IS_TRANSITION(x, y) ((x) * (y) < 0)
188#define DECREASE_DURATION(duration, amount) \
189 do { \
190 if (IS_SPACE(duration)) \
191 duration += (amount); \
192 else if (IS_PULSE(duration)) \
193 duration -= (amount); \
194 } while (0)
195
196#define TO_UNITS(duration, unit_len) \
197 ((int)((duration) > 0 ? \
198 DIV_ROUND_CLOSEST(abs((duration)), (unit_len)) :\
199 -DIV_ROUND_CLOSEST(abs((duration)), (unit_len))))
200#define TO_US(duration) ((int)TO_UNITS(duration, 1000))
201
177#endif /* _IR_CORE */ 202#endif /* _IR_CORE */