V4L/DVB: ir-core: move decoding state to ir_raw_event_ctrl
authorDavid Härdeman <david@hardeman.nu>
Sun, 13 Jun 2010 20:29:36 +0000 (17:29 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 2 Aug 2010 17:55:15 +0000 (14:55 -0300)
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>
drivers/media/IR/ir-core-priv.h
drivers/media/IR/ir-jvc-decoder.c
drivers/media/IR/ir-nec-decoder.c
drivers/media/IR/ir-raw-event.c
drivers/media/IR/ir-rc5-decoder.c
drivers/media/IR/ir-rc6-decoder.c
drivers/media/IR/ir-sony-decoder.c

index 5111dc23909ac67cf34bb4fb5e3fe63acae0309c..0a82b22d38281d44049335209cebb68ce2988b4e 100644 (file)
@@ -24,17 +24,55 @@ struct ir_raw_handler {
 
        u64 protocols; /* which are handled by this handler */
        int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
+
+       /* These two should only be used by the lirc decoder */
        int (*raw_register)(struct input_dev *input_dev);
        int (*raw_unregister)(struct input_dev *input_dev);
 };
 
 struct ir_raw_event_ctrl {
+       struct list_head                list;           /* to keep track of raw clients */
        struct work_struct              rx_work;        /* for the rx decoding workqueue */
        struct kfifo                    kfifo;          /* fifo for the pulse/space durations */
        ktime_t                         last_event;     /* when last event occurred */
        enum raw_event_type             last_type;      /* last event type */
        struct input_dev                *input_dev;     /* pointer to the parent input_dev */
        u64                             enabled_protocols; /* enabled raw protocol decoders */
+
+       /* raw decoder state follows */
+       struct ir_raw_event prev_ev;
+       struct nec_dec {
+               int state;
+               unsigned count;
+               u32 bits;
+       } nec;
+       struct rc5_dec {
+               int state;
+               u32 bits;
+               unsigned count;
+               unsigned wanted_bits;
+       } rc5;
+       struct rc6_dec {
+               int state;
+               u8 header;
+               u32 body;
+               bool toggle;
+               unsigned count;
+               unsigned wanted_bits;
+       } rc6;
+       struct sony_dec {
+               int state;
+               u32 bits;
+               unsigned count;
+       } sony;
+       struct jvc_dec {
+               int state;
+               u16 bits;
+               u16 old_bits;
+               unsigned count;
+               bool first;
+               bool toggle;
+       } jvc;
 };
 
 /* macros for IR decoders */
index b1f935884d3092f9c4b6dcd5fc91c722a34da5b9..8894d8b360486e56595efbf6617a14925c0ea67e 100644 (file)
 #define JVC_TRAILER_PULSE      (1  * JVC_UNIT)
 #define        JVC_TRAILER_SPACE       (35 * JVC_UNIT)
 
-/* Used to register jvc_decoder clients */
-static LIST_HEAD(decoder_list);
-DEFINE_SPINLOCK(decoder_lock);
-
 enum jvc_state {
        STATE_INACTIVE,
        STATE_HEADER_SPACE,
@@ -38,39 +34,6 @@ enum jvc_state {
        STATE_TRAILER_SPACE,
 };
 
-struct decoder_data {
-       struct list_head        list;
-       struct ir_input_dev     *ir_dev;
-
-       /* State machine control */
-       enum jvc_state          state;
-       u16                     jvc_bits;
-       u16                     jvc_old_bits;
-       unsigned                count;
-       bool                    first;
-       bool                    toggle;
-};
-
-
-/**
- * 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)
-{
-       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;
-}
-
 /**
  * ir_jvc_decode() - Decode one JVC pulse or space
  * @input_dev: the struct input_dev descriptor of the device
@@ -80,12 +43,8 @@ static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
  */
 static int ir_jvc_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);
-
-       data = get_decoder_data(ir_dev);
-       if (!data)
-               return -EINVAL;
+       struct jvc_dec *data = &ir_dev->raw->jvc;
 
        if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
                return 0;
@@ -140,9 +99,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
                if (ev.pulse)
                        break;
 
-               data->jvc_bits <<= 1;
+               data->bits <<= 1;
                if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
-                       data->jvc_bits |= 1;
+                       data->bits |= 1;
                        decrease_duration(&ev, JVC_BIT_1_SPACE);
                } else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
                        decrease_duration(&ev, JVC_BIT_0_SPACE);
@@ -175,13 +134,13 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 
                if (data->first) {
                        u32 scancode;
-                       scancode = (bitrev8((data->jvc_bits >> 8) & 0xff) << 8) |
-                                  (bitrev8((data->jvc_bits >> 0) & 0xff) << 0);
+                       scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
+                                  (bitrev8((data->bits >> 0) & 0xff) << 0);
                        IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
                        ir_keydown(input_dev, scancode, data->toggle);
                        data->first = false;
-                       data->jvc_old_bits = data->jvc_bits;
-               } else if (data->jvc_bits == data->jvc_old_bits) {
+                       data->old_bits = data->bits;
+               } else if (data->bits == data->old_bits) {
                        IR_dprintk(1, "JVC repeat\n");
                        ir_repeat(input_dev);
                } else {
@@ -201,45 +160,9 @@ out:
        return -EINVAL;
 }
 
-static int ir_jvc_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_jvc_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 jvc_handler = {
        .protocols      = IR_TYPE_JVC,
        .decode         = ir_jvc_decode,
-       .raw_register   = ir_jvc_register,
-       .raw_unregister = ir_jvc_unregister,
 };
 
 static int __init ir_jvc_decode_init(void)
index db62c652dfc590ed1cbef3ee2317848159ae1306..52e0f378ae3df2b25a329bd1e0da1e3ba22ec834 100644 (file)
 #define        NEC_TRAILER_PULSE       (1  * NEC_UNIT)
 #define        NEC_TRAILER_SPACE       (10 * NEC_UNIT) /* even longer in reality */
 
-/* Used to register nec_decoder clients */
-static LIST_HEAD(decoder_list);
-static DEFINE_SPINLOCK(decoder_lock);
-
 enum nec_state {
        STATE_INACTIVE,
        STATE_HEADER_SPACE,
@@ -40,36 +36,6 @@ enum nec_state {
        STATE_TRAILER_SPACE,
 };
 
-struct decoder_data {
-       struct list_head        list;
-       struct ir_input_dev     *ir_dev;
-
-       /* State machine control */
-       enum nec_state          state;
-       u32                     nec_bits;
-       unsigned                count;
-};
-
-
-/**
- * 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)
-{
-       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;
-}
-
 /**
  * ir_nec_decode() - Decode one NEC pulse or space
  * @input_dev: the struct input_dev descriptor of the device
@@ -79,15 +45,11 @@ static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
  */
 static int ir_nec_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 nec_dec *data = &ir_dev->raw->nec;
        u32 scancode;
        u8 address, not_address, command, not_command;
 
-       data = get_decoder_data(ir_dev);
-       if (!data)
-               return -EINVAL;
-
        if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
                return 0;
 
@@ -143,9 +105,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
                if (ev.pulse)
                        break;
 
-               data->nec_bits <<= 1;
+               data->bits <<= 1;
                if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
-                       data->nec_bits |= 1;
+                       data->bits |= 1;
                else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
                        break;
                data->count++;
@@ -174,14 +136,14 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
                if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
                        break;
 
-               address     = bitrev8((data->nec_bits >> 24) & 0xff);
-               not_address = bitrev8((data->nec_bits >> 16) & 0xff);
-               command     = bitrev8((data->nec_bits >>  8) & 0xff);
-               not_command = bitrev8((data->nec_bits >>  0) & 0xff);
+               address     = bitrev8((data->bits >> 24) & 0xff);
+               not_address = bitrev8((data->bits >> 16) & 0xff);
+               command     = bitrev8((data->bits >>  8) & 0xff);
+               not_command = bitrev8((data->bits >>  0) & 0xff);
 
                if ((command ^ not_command) != 0xff) {
                        IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
-                                  data->nec_bits);
+                                  data->bits);
                        break;
                }
 
@@ -208,45 +170,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
        return -EINVAL;
 }
 
-static int ir_nec_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_nec_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 nec_handler = {
        .protocols      = IR_TYPE_NEC,
        .decode         = ir_nec_decode,
-       .raw_register   = ir_nec_register,
-       .raw_unregister = ir_nec_unregister,
 };
 
 static int __init ir_nec_decode_init(void)
index fb3336c37191290049845a48181e299a30997b0a..5f98ab823057732a5e666791217105c8fb079aec 100644 (file)
 /* Define the max number of pulse/space transitions to buffer */
 #define MAX_IR_EVENT_SIZE      512
 
+/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */
+static LIST_HEAD(ir_raw_client_list);
+
 /* Used to handle IR raw handler extensions */
 static DEFINE_SPINLOCK(ir_raw_handler_lock);
 static LIST_HEAD(ir_raw_handler_list);
 static u64 available_protocols;
 
-/**
- * RUN_DECODER()       - runs an operation on all IR decoders
- * @ops:       IR raw handler operation to be called
- * @arg:       arguments to be passed to the callback
- *
- * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
- * new decode addition/removal while running, by locking ir_raw_handler_lock
- * mutex. If an error occurs, we keep going, as in the decode case, each
- * decoder must have a crack at decoding the data. We return a sum of the
- * return codes, which will be either 0 or negative for current callers.
- */
-#define RUN_DECODER(ops, ...) ({                                           \
-       struct ir_raw_handler           *_ir_raw_handler;                   \
-       int _sumrc = 0, _rc;                                                \
-       spin_lock(&ir_raw_handler_lock);                                    \
-       list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) {  \
-               if (_ir_raw_handler->ops) {                                 \
-                       _rc = _ir_raw_handler->ops(__VA_ARGS__);            \
-                       _sumrc += _rc;                                      \
-               }                                                           \
-       }                                                                   \
-       spin_unlock(&ir_raw_handler_lock);                                  \
-       _sumrc;                                                             \
-})
-
 #ifdef MODULE
 /* Used to load the decoders */
 static struct work_struct wq_load;
@@ -58,11 +36,17 @@ static struct work_struct wq_load;
 static void ir_raw_event_work(struct work_struct *work)
 {
        struct ir_raw_event ev;
+       struct ir_raw_handler *handler;
        struct ir_raw_event_ctrl *raw =
                container_of(work, struct ir_raw_event_ctrl, rx_work);
 
-       while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
-               RUN_DECODER(decode, raw->input_dev, ev);
+       while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
+               spin_lock(&ir_raw_handler_lock);
+               list_for_each_entry(handler, &ir_raw_handler_list, list)
+                       handler->decode(raw->input_dev, ev);
+               spin_unlock(&ir_raw_handler_lock);
+               raw->prev_ev = ev;
+       }
 }
 
 /**
@@ -176,6 +160,7 @@ int ir_raw_event_register(struct input_dev *input_dev)
 {
        struct ir_input_dev *ir = input_get_drvdata(input_dev);
        int rc;
+       struct ir_raw_handler *handler;
 
        ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
        if (!ir->raw)
@@ -192,26 +177,32 @@ int ir_raw_event_register(struct input_dev *input_dev)
                return rc;
        }
 
-       rc = RUN_DECODER(raw_register, input_dev);
-       if (rc < 0) {
-               kfifo_free(&ir->raw->kfifo);
-               kfree(ir->raw);
-               ir->raw = NULL;
-               return rc;
-       }
+       spin_lock(&ir_raw_handler_lock);
+       list_add_tail(&ir->raw->list, &ir_raw_client_list);
+       list_for_each_entry(handler, &ir_raw_handler_list, list)
+               if (handler->raw_register)
+                       handler->raw_register(ir->raw->input_dev);
+       spin_unlock(&ir_raw_handler_lock);
 
-       return rc;
+       return 0;
 }
 
 void ir_raw_event_unregister(struct input_dev *input_dev)
 {
        struct ir_input_dev *ir = input_get_drvdata(input_dev);
+       struct ir_raw_handler *handler;
 
        if (!ir->raw)
                return;
 
        cancel_work_sync(&ir->raw->rx_work);
-       RUN_DECODER(raw_unregister, input_dev);
+
+       spin_lock(&ir_raw_handler_lock);
+       list_del(&ir->raw->list);
+       list_for_each_entry(handler, &ir_raw_handler_list, list)
+               if (handler->raw_unregister)
+                       handler->raw_unregister(ir->raw->input_dev);
+       spin_unlock(&ir_raw_handler_lock);
 
        kfifo_free(&ir->raw->kfifo);
        kfree(ir->raw);
@@ -224,8 +215,13 @@ void ir_raw_event_unregister(struct input_dev *input_dev)
 
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
 {
+       struct ir_raw_event_ctrl *raw;
+
        spin_lock(&ir_raw_handler_lock);
        list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
+       if (ir_raw_handler->raw_register)
+               list_for_each_entry(raw, &ir_raw_client_list, list)
+                       ir_raw_handler->raw_register(raw->input_dev);
        available_protocols |= ir_raw_handler->protocols;
        spin_unlock(&ir_raw_handler_lock);
 
@@ -235,8 +231,13 @@ EXPORT_SYMBOL(ir_raw_handler_register);
 
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
 {
+       struct ir_raw_event_ctrl *raw;
+
        spin_lock(&ir_raw_handler_lock);
        list_del(&ir_raw_handler->list);
+       if (ir_raw_handler->raw_unregister)
+               list_for_each_entry(raw, &ir_raw_client_list, list)
+                       ir_raw_handler->raw_unregister(raw->input_dev);
        available_protocols &= ~ir_raw_handler->protocols;
        spin_unlock(&ir_raw_handler_lock);
 }
index bdfa404a6537f47102ebef551a5013cb1855a74c..df4770d978ad835201ec31341d122f3011db9427 100644 (file)
 #define RC5_BIT_END            (1 * RC5_UNIT)
 #define RC5X_SPACE             (4 * RC5_UNIT)
 
-/* Used to register rc5_decoder clients */
-static LIST_HEAD(decoder_list);
-static DEFINE_SPINLOCK(decoder_lock);
-
 enum rc5_state {
        STATE_INACTIVE,
        STATE_BIT_START,
@@ -42,39 +38,6 @@ enum rc5_state {
        STATE_FINISHED,
 };
 
-struct decoder_data {
-       struct list_head        list;
-       struct ir_input_dev     *ir_dev;
-
-       /* State machine control */
-       enum rc5_state          state;
-       u32                     rc5_bits;
-       struct ir_raw_event     prev_ev;
-       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)
-{
-       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;
-}
-
 /**
  * ir_rc5_decode() - Decode one RC-5 pulse or space
  * @input_dev: the struct input_dev descriptor of the device
@@ -84,15 +47,11 @@ static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
  */
 static int ir_rc5_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 rc5_dec *data = &ir_dev->raw->rc5;
        u8 toggle;
        u32 scancode;
 
-       data = get_decoder_data(ir_dev);
-       if (!data)
-               return -EINVAL;
-
         if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
                 return 0;
 
@@ -128,16 +87,15 @@ again:
                if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
                        break;
 
-               data->rc5_bits <<= 1;
+               data->bits <<= 1;
                if (!ev.pulse)
-                       data->rc5_bits |= 1;
+                       data->bits |= 1;
                data->count++;
-               data->prev_ev = ev;
                data->state = STATE_BIT_END;
                return 0;
 
        case STATE_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)
@@ -169,11 +127,11 @@ again:
                if (data->wanted_bits == RC5X_NBITS) {
                        /* RC5X */
                        u8 xdata, command, system;
-                       xdata    = (data->rc5_bits & 0x0003F) >> 0;
-                       command  = (data->rc5_bits & 0x00FC0) >> 6;
-                       system   = (data->rc5_bits & 0x1F000) >> 12;
-                       toggle   = (data->rc5_bits & 0x20000) ? 1 : 0;
-                       command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
+                       xdata    = (data->bits & 0x0003F) >> 0;
+                       command  = (data->bits & 0x00FC0) >> 6;
+                       system   = (data->bits & 0x1F000) >> 12;
+                       toggle   = (data->bits & 0x20000) ? 1 : 0;
+                       command += (data->bits & 0x01000) ? 0 : 0x40;
                        scancode = system << 16 | command << 8 | xdata;
 
                        IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
@@ -182,10 +140,10 @@ again:
                } else {
                        /* RC5 */
                        u8 command, system;
-                       command  = (data->rc5_bits & 0x0003F) >> 0;
-                       system   = (data->rc5_bits & 0x007C0) >> 6;
-                       toggle   = (data->rc5_bits & 0x00800) ? 1 : 0;
-                       command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
+                       command  = (data->bits & 0x0003F) >> 0;
+                       system   = (data->bits & 0x007C0) >> 6;
+                       toggle   = (data->bits & 0x00800) ? 1 : 0;
+                       command += (data->bits & 0x01000) ? 0 : 0x40;
                        scancode = system << 8 | command;
 
                        IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
@@ -204,45 +162,9 @@ out:
        return -EINVAL;
 }
 
-static int ir_rc5_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_rc5_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 rc5_handler = {
        .protocols      = IR_TYPE_RC5,
        .decode         = ir_rc5_decode,
-       .raw_register   = ir_rc5_register,
-       .raw_unregister = ir_rc5_unregister,
 };
 
 static int __init ir_rc5_decode_init(void)
index 2ebd4ea69538335bf62a84ec7cecb8d7f6172f0f..f1624b8279bcce2d581c567cf0840b38ebfc4bc2 100644 (file)
 #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)
index e15db3334998f9527a456ea2545e742278cca9e0..b9074f07c7a0570293e46eebb8981900da862035 100644 (file)
 #define SONY_BIT_SPACE         (1 * SONY_UNIT)
 #define SONY_TRAILER_SPACE     (10 * SONY_UNIT) /* minimum */
 
-/* Used to register sony_decoder clients */
-static LIST_HEAD(decoder_list);
-static DEFINE_SPINLOCK(decoder_lock);
-
 enum sony_state {
        STATE_INACTIVE,
        STATE_HEADER_SPACE,
@@ -35,36 +31,6 @@ enum sony_state {
        STATE_FINISHED,
 };
 
-struct decoder_data {
-       struct list_head        list;
-       struct ir_input_dev     *ir_dev;
-
-       /* State machine control */
-       enum sony_state         state;
-       u32                     sony_bits;
-       unsigned                count;
-};
-
-
-/**
- * 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)
-{
-       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;
-}
-
 /**
  * ir_sony_decode() - Decode one Sony pulse or space
  * @input_dev: the struct input_dev descriptor of the device
@@ -74,15 +40,11 @@ static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
  */
 static int ir_sony_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 sony_dec *data = &ir_dev->raw->sony;
        u32 scancode;
        u8 device, subdevice, function;
 
-       data = get_decoder_data(ir_dev);
-       if (!data)
-               return -EINVAL;
-
        if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
                return 0;
 
@@ -124,9 +86,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
                if (!ev.pulse)
                        break;
 
-               data->sony_bits <<= 1;
+               data->bits <<= 1;
                if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
-                       data->sony_bits |= 1;
+                       data->bits |= 1;
                else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
                        break;
 
@@ -160,19 +122,19 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 
                switch (data->count) {
                case 12:
-                       device    = bitrev8((data->sony_bits <<  3) & 0xF8);
+                       device    = bitrev8((data->bits <<  3) & 0xF8);
                        subdevice = 0;
-                       function  = bitrev8((data->sony_bits >>  4) & 0xFE);
+                       function  = bitrev8((data->bits >>  4) & 0xFE);
                        break;
                case 15:
-                       device    = bitrev8((data->sony_bits >>  0) & 0xFF);
+                       device    = bitrev8((data->bits >>  0) & 0xFF);
                        subdevice = 0;
-                       function  = bitrev8((data->sony_bits >>  7) & 0xFD);
+                       function  = bitrev8((data->bits >>  7) & 0xFD);
                        break;
                case 20:
-                       device    = bitrev8((data->sony_bits >>  5) & 0xF8);
-                       subdevice = bitrev8((data->sony_bits >>  0) & 0xFF);
-                       function  = bitrev8((data->sony_bits >> 12) & 0xFE);
+                       device    = bitrev8((data->bits >>  5) & 0xF8);
+                       subdevice = bitrev8((data->bits >>  0) & 0xFF);
+                       function  = bitrev8((data->bits >> 12) & 0xFE);
                        break;
                default:
                        IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
@@ -193,45 +155,9 @@ out:
        return -EINVAL;
 }
 
-static int ir_sony_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_sony_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 sony_handler = {
        .protocols      = IR_TYPE_SONY,
        .decode         = ir_sony_decode,
-       .raw_register   = ir_sony_register,
-       .raw_unregister = ir_sony_unregister,
 };
 
 static int __init ir_sony_decode_init(void)