summaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-rc6-decoder.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2010-06-13 17:29:36 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-02 14:55:15 -0300
commitc216369e61fae586cd48c0913cca2a37fbfeb912 (patch)
treec4dfc55e6b4673a2e5698bd1f8aa8ae3919f57f7 /drivers/media/IR/ir-rc6-decoder.c
parentde8592bd539b2bb8da2b55b1007562eb1abd1fe6 (diff)
V4L/DVB: ir-core: move decoding state to ir_raw_event_ctrl
This patch moves the state from each raw decoder into the ir_raw_event_ctrl struct. This allows the removal of code like this: spin_lock(&decoder_lock); list_for_each_entry(data, &decoder_list, list) { if (data->ir_dev == ir_dev) break; } spin_unlock(&decoder_lock); return data; which is currently run for each decoder on each event in order to get the client-specific decoding state data. In addition, ir decoding modules and ir driver module load order is now independent. Centralizing the data also allows for a nice code reduction of about 30% per raw decoder as client lists and client registration callbacks are no longer necessary (but still kept around for the benefit of the lirc decoder). Out-of-tree modules can still use a similar trick to what the raw decoders did before this patch until they are merged. Signed-off-by: David Härdeman <david@hardeman.nu> Acked-by: Jarod Wilson <jarod@redhat.com> Tested-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/ir-rc6-decoder.c')
-rw-r--r--drivers/media/IR/ir-rc6-decoder.c92
1 files changed, 5 insertions, 87 deletions
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
index 2ebd4ea6953..f1624b8279b 100644
--- a/drivers/media/IR/ir-rc6-decoder.c
+++ b/drivers/media/IR/ir-rc6-decoder.c
@@ -36,10 +36,6 @@
#define RC6_STARTBIT_MASK 0x08 /* for the header bits */
#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
-/* Used to register rc6_decoder clients */
-static LIST_HEAD(decoder_list);
-static DEFINE_SPINLOCK(decoder_lock);
-
enum rc6_mode {
RC6_MODE_0,
RC6_MODE_6A,
@@ -58,41 +54,8 @@ enum rc6_state {
STATE_FINISHED,
};
-struct decoder_data {
- struct list_head list;
- struct ir_input_dev *ir_dev;
-
- /* State machine control */
- enum rc6_state state;
- u8 header;
- u32 body;
- struct ir_raw_event prev_ev;
- bool toggle;
- unsigned count;
- unsigned wanted_bits;
-};
-
-
-/**
- * get_decoder_data() - gets decoder data
- * @input_dev: input device
- *
- * Returns the struct decoder_data that corresponds to a device
- */
-static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
+static enum rc6_mode rc6_mode(struct rc6_dec *data)
{
- struct decoder_data *data = NULL;
-
- spin_lock(&decoder_lock);
- list_for_each_entry(data, &decoder_list, list) {
- if (data->ir_dev == ir_dev)
- break;
- }
- spin_unlock(&decoder_lock);
- return data;
-}
-
-static enum rc6_mode rc6_mode(struct decoder_data *data) {
switch (data->header & RC6_MODE_MASK) {
case 0:
return RC6_MODE_0;
@@ -114,15 +77,11 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) {
*/
static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
- struct decoder_data *data;
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct rc6_dec *data = &ir_dev->raw->rc6;
u32 scancode;
u8 toggle;
- data = get_decoder_data(ir_dev);
- if (!data)
- return -EINVAL;
-
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
return 0;
@@ -175,12 +134,11 @@ again:
if (ev.pulse)
data->header |= 1;
data->count++;
- data->prev_ev = ev;
data->state = STATE_HEADER_BIT_END;
return 0;
case STATE_HEADER_BIT_END:
- if (!is_transition(&ev, &data->prev_ev))
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break;
if (data->count == RC6_HEADER_NBITS)
@@ -196,12 +154,11 @@ again:
break;
data->toggle = ev.pulse;
- data->prev_ev = ev;
data->state = STATE_TOGGLE_END;
return 0;
case STATE_TOGGLE_END:
- if (!is_transition(&ev, &data->prev_ev) ||
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
!geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
break;
@@ -211,7 +168,6 @@ again:
}
data->state = STATE_BODY_BIT_START;
- data->prev_ev = ev;
decrease_duration(&ev, RC6_TOGGLE_END);
data->count = 0;
@@ -243,13 +199,11 @@ again:
if (ev.pulse)
data->body |= 1;
data->count++;
- data->prev_ev = ev;
-
data->state = STATE_BODY_BIT_END;
return 0;
case STATE_BODY_BIT_END:
- if (!is_transition(&ev, &data->prev_ev))
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -300,45 +254,9 @@ out:
return -EINVAL;
}
-static int ir_rc6_register(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct decoder_data *data;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- data->ir_dev = ir_dev;
-
- spin_lock(&decoder_lock);
- list_add_tail(&data->list, &decoder_list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
-static int ir_rc6_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- static struct decoder_data *data;
-
- data = get_decoder_data(ir_dev);
- if (!data)
- return 0;
-
- spin_lock(&decoder_lock);
- list_del(&data->list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
static struct ir_raw_handler rc6_handler = {
.protocols = IR_TYPE_RC6,
.decode = ir_rc6_decode,
- .raw_register = ir_rc6_register,
- .raw_unregister = ir_rc6_unregister,
};
static int __init ir_rc6_decode_init(void)