Commit c216369e authored by David Härdeman's avatar David Härdeman Committed by Mauro Carvalho Chehab

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: default avatarDavid Härdeman <david@hardeman.nu>
Acked-by: default avatarJarod Wilson <jarod@redhat.com>
Tested-by: default avatarJarod Wilson <jarod@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent de8592bd
...@@ -24,17 +24,55 @@ struct ir_raw_handler { ...@@ -24,17 +24,55 @@ struct ir_raw_handler {
u64 protocols; /* which are handled by this handler */ u64 protocols; /* which are handled by this handler */
int (*decode)(struct input_dev *input_dev, struct ir_raw_event event); 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_register)(struct input_dev *input_dev);
int (*raw_unregister)(struct input_dev *input_dev); int (*raw_unregister)(struct input_dev *input_dev);
}; };
struct ir_raw_event_ctrl { 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 work_struct rx_work; /* for the rx decoding workqueue */
struct kfifo kfifo; /* fifo for the pulse/space durations */ struct kfifo kfifo; /* fifo for the pulse/space durations */
ktime_t last_event; /* when last event occurred */ ktime_t last_event; /* when last event occurred */
enum raw_event_type last_type; /* last event type */ enum raw_event_type last_type; /* last event type */
struct input_dev *input_dev; /* pointer to the parent input_dev */ struct input_dev *input_dev; /* pointer to the parent input_dev */
u64 enabled_protocols; /* enabled raw protocol decoders */ 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 */ /* macros for IR decoders */
......
...@@ -25,10 +25,6 @@ ...@@ -25,10 +25,6 @@
#define JVC_TRAILER_PULSE (1 * JVC_UNIT) #define JVC_TRAILER_PULSE (1 * JVC_UNIT)
#define JVC_TRAILER_SPACE (35 * 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 { enum jvc_state {
STATE_INACTIVE, STATE_INACTIVE,
STATE_HEADER_SPACE, STATE_HEADER_SPACE,
...@@ -38,39 +34,6 @@ enum jvc_state { ...@@ -38,39 +34,6 @@ enum jvc_state {
STATE_TRAILER_SPACE, 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 * ir_jvc_decode() - Decode one JVC pulse or space
* @input_dev: the struct input_dev descriptor of the device * @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) ...@@ -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) 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); struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct jvc_dec *data = &ir_dev->raw->jvc;
data = get_decoder_data(ir_dev);
if (!data)
return -EINVAL;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC)) if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
return 0; return 0;
...@@ -140,9 +99,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -140,9 +99,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (ev.pulse) if (ev.pulse)
break; break;
data->jvc_bits <<= 1; data->bits <<= 1;
if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) { 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); decrease_duration(&ev, JVC_BIT_1_SPACE);
} else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2)) } else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
decrease_duration(&ev, JVC_BIT_0_SPACE); 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) ...@@ -175,13 +134,13 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (data->first) { if (data->first) {
u32 scancode; u32 scancode;
scancode = (bitrev8((data->jvc_bits >> 8) & 0xff) << 8) | scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
(bitrev8((data->jvc_bits >> 0) & 0xff) << 0); (bitrev8((data->bits >> 0) & 0xff) << 0);
IR_dprintk(1, "JVC scancode 0x%04x\n", scancode); IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
ir_keydown(input_dev, scancode, data->toggle); ir_keydown(input_dev, scancode, data->toggle);
data->first = false; data->first = false;
data->jvc_old_bits = data->jvc_bits; data->old_bits = data->bits;
} else if (data->jvc_bits == data->jvc_old_bits) { } else if (data->bits == data->old_bits) {
IR_dprintk(1, "JVC repeat\n"); IR_dprintk(1, "JVC repeat\n");
ir_repeat(input_dev); ir_repeat(input_dev);
} else { } else {
...@@ -201,45 +160,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -201,45 +160,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
return -EINVAL; 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 = { static struct ir_raw_handler jvc_handler = {
.protocols = IR_TYPE_JVC, .protocols = IR_TYPE_JVC,
.decode = ir_jvc_decode, .decode = ir_jvc_decode,
.raw_register = ir_jvc_register,
.raw_unregister = ir_jvc_unregister,
}; };
static int __init ir_jvc_decode_init(void) static int __init ir_jvc_decode_init(void)
......
...@@ -27,10 +27,6 @@ ...@@ -27,10 +27,6 @@
#define NEC_TRAILER_PULSE (1 * NEC_UNIT) #define NEC_TRAILER_PULSE (1 * NEC_UNIT)
#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */ #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 { enum nec_state {
STATE_INACTIVE, STATE_INACTIVE,
STATE_HEADER_SPACE, STATE_HEADER_SPACE,
...@@ -40,36 +36,6 @@ enum nec_state { ...@@ -40,36 +36,6 @@ enum nec_state {
STATE_TRAILER_SPACE, 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 * ir_nec_decode() - Decode one NEC pulse or space
* @input_dev: the struct input_dev descriptor of the device * @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) ...@@ -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) 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 ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct nec_dec *data = &ir_dev->raw->nec;
u32 scancode; u32 scancode;
u8 address, not_address, command, not_command; 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)) if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
return 0; return 0;
...@@ -143,9 +105,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -143,9 +105,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (ev.pulse) if (ev.pulse)
break; break;
data->nec_bits <<= 1; data->bits <<= 1;
if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) 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)) else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
break; break;
data->count++; data->count++;
...@@ -174,14 +136,14 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -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)) if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
break; break;
address = bitrev8((data->nec_bits >> 24) & 0xff); address = bitrev8((data->bits >> 24) & 0xff);
not_address = bitrev8((data->nec_bits >> 16) & 0xff); not_address = bitrev8((data->bits >> 16) & 0xff);
command = bitrev8((data->nec_bits >> 8) & 0xff); command = bitrev8((data->bits >> 8) & 0xff);
not_command = bitrev8((data->nec_bits >> 0) & 0xff); not_command = bitrev8((data->bits >> 0) & 0xff);
if ((command ^ not_command) != 0xff) { if ((command ^ not_command) != 0xff) {
IR_dprintk(1, "NEC checksum error: received 0x%08x\n", IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
data->nec_bits); data->bits);
break; break;
} }
...@@ -208,45 +170,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -208,45 +170,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
return -EINVAL; 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 = { static struct ir_raw_handler nec_handler = {
.protocols = IR_TYPE_NEC, .protocols = IR_TYPE_NEC,
.decode = ir_nec_decode, .decode = ir_nec_decode,
.raw_register = ir_nec_register,
.raw_unregister = ir_nec_unregister,
}; };
static int __init ir_nec_decode_init(void) static int __init ir_nec_decode_init(void)
......
...@@ -20,36 +20,14 @@ ...@@ -20,36 +20,14 @@
/* Define the max number of pulse/space transitions to buffer */ /* Define the max number of pulse/space transitions to buffer */
#define MAX_IR_EVENT_SIZE 512 #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 */ /* Used to handle IR raw handler extensions */
static DEFINE_SPINLOCK(ir_raw_handler_lock); static DEFINE_SPINLOCK(ir_raw_handler_lock);
static LIST_HEAD(ir_raw_handler_list); static LIST_HEAD(ir_raw_handler_list);
static u64 available_protocols; 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 #ifdef MODULE
/* Used to load the decoders */ /* Used to load the decoders */
static struct work_struct wq_load; static struct work_struct wq_load;
...@@ -58,11 +36,17 @@ 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) static void ir_raw_event_work(struct work_struct *work)
{ {
struct ir_raw_event ev; struct ir_raw_event ev;
struct ir_raw_handler *handler;
struct ir_raw_event_ctrl *raw = struct ir_raw_event_ctrl *raw =
container_of(work, struct ir_raw_event_ctrl, rx_work); container_of(work, struct ir_raw_event_ctrl, rx_work);
while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
RUN_DECODER(decode, raw->input_dev, 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) ...@@ -176,6 +160,7 @@ int ir_raw_event_register(struct input_dev *input_dev)
{ {
struct ir_input_dev *ir = input_get_drvdata(input_dev); struct ir_input_dev *ir = input_get_drvdata(input_dev);
int rc; int rc;
struct ir_raw_handler *handler;
ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
if (!ir->raw) if (!ir->raw)
...@@ -192,26 +177,32 @@ int ir_raw_event_register(struct input_dev *input_dev) ...@@ -192,26 +177,32 @@ int ir_raw_event_register(struct input_dev *input_dev)
return rc; return rc;
} }
rc = RUN_DECODER(raw_register, input_dev); spin_lock(&ir_raw_handler_lock);
if (rc < 0) { list_add_tail(&ir->raw->list, &ir_raw_client_list);
kfifo_free(&ir->raw->kfifo); list_for_each_entry(handler, &ir_raw_handler_list, list)
kfree(ir->raw); if (handler->raw_register)
ir->raw = NULL; handler->raw_register(ir->raw->input_dev);
return rc; spin_unlock(&ir_raw_handler_lock);
}
return rc; return 0;
} }
void ir_raw_event_unregister(struct input_dev *input_dev) void ir_raw_event_unregister(struct input_dev *input_dev)
{ {
struct ir_input_dev *ir = input_get_drvdata(input_dev); struct ir_input_dev *ir = input_get_drvdata(input_dev);
struct ir_raw_handler *handler;
if (!ir->raw) if (!ir->raw)
return; return;
cancel_work_sync(&ir->raw->rx_work); 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); kfifo_free(&ir->raw->kfifo);
kfree(ir->raw); kfree(ir->raw);
...@@ -224,8 +215,13 @@ void ir_raw_event_unregister(struct input_dev *input_dev) ...@@ -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) int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
{ {
struct ir_raw_event_ctrl *raw;
spin_lock(&ir_raw_handler_lock); spin_lock(&ir_raw_handler_lock);
list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); 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; available_protocols |= ir_raw_handler->protocols;
spin_unlock(&ir_raw_handler_lock); spin_unlock(&ir_raw_handler_lock);
...@@ -235,8 +231,13 @@ EXPORT_SYMBOL(ir_raw_handler_register); ...@@ -235,8 +231,13 @@ EXPORT_SYMBOL(ir_raw_handler_register);
void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
{ {
struct ir_raw_event_ctrl *raw;
spin_lock(&ir_raw_handler_lock); spin_lock(&ir_raw_handler_lock);
list_del(&ir_raw_handler->list); 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; available_protocols &= ~ir_raw_handler->protocols;
spin_unlock(&ir_raw_handler_lock); spin_unlock(&ir_raw_handler_lock);
} }
......
...@@ -30,10 +30,6 @@ ...@@ -30,10 +30,6 @@
#define RC5_BIT_END (1 * RC5_UNIT) #define RC5_BIT_END (1 * RC5_UNIT)
#define RC5X_SPACE (4 * 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 { enum rc5_state {
STATE_INACTIVE, STATE_INACTIVE,
STATE_BIT_START, STATE_BIT_START,
...@@ -42,39 +38,6 @@ enum rc5_state { ...@@ -42,39 +38,6 @@ enum rc5_state {
STATE_FINISHED, 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 * ir_rc5_decode() - Decode one RC-5 pulse or space
* @input_dev: the struct input_dev descriptor of the device * @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) ...@@ -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) 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 ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct rc5_dec *data = &ir_dev->raw->rc5;
u8 toggle; u8 toggle;
u32 scancode; u32 scancode;
data = get_decoder_data(ir_dev);
if (!data)
return -EINVAL;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
return 0; return 0;
...@@ -128,16 +87,15 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -128,16 +87,15 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
break; break;
data->rc5_bits <<= 1; data->bits <<= 1;
if (!ev.pulse) if (!ev.pulse)
data->rc5_bits |= 1; data->bits |= 1;
data->count++; data->count++;
data->prev_ev = ev;
data->state = STATE_BIT_END; data->state = STATE_BIT_END;
return 0; return 0;
case STATE_BIT_END: case STATE_BIT_END:
if (!is_transition(&ev, &data->prev_ev)) if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break; break;
if (data->count == data->wanted_bits) if (data->count == data->wanted_bits)
...@@ -169,11 +127,11 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -169,11 +127,11 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (data->wanted_bits == RC5X_NBITS) { if (data->wanted_bits == RC5X_NBITS) {
/* RC5X */ /* RC5X */
u8 xdata, command, system; u8 xdata, command, system;
xdata = (data->rc5_bits & 0x0003F) >> 0; xdata = (data->bits & 0x0003F) >> 0;
command = (data->rc5_bits & 0x00FC0) >> 6; command = (data->bits & 0x00FC0) >> 6;
system = (data->rc5_bits & 0x1F000) >> 12; system = (data->bits & 0x1F000) >> 12;
toggle = (data->rc5_bits & 0x20000) ? 1 : 0; toggle = (data->bits & 0x20000) ? 1 : 0;
command += (data->rc5_bits & 0x01000) ? 0 : 0x40; command += (data->bits & 0x01000) ? 0 : 0x40;
scancode = system << 16 | command << 8 | xdata; scancode = system << 16 | command << 8 | xdata;
IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n", IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
...@@ -182,10 +140,10 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -182,10 +140,10 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
} else { } else {
/* RC5 */ /* RC5 */
u8 command, system; u8 command, system;
command = (data->rc5_bits & 0x0003F) >> 0; command = (data->bits & 0x0003F) >> 0;
system = (data->rc5_bits & 0x007C0) >> 6; system = (data->bits & 0x007C0) >> 6;
toggle = (data->rc5_bits & 0x00800) ? 1 : 0; toggle = (data->bits & 0x00800) ? 1 : 0;
command += (data->rc5_bits & 0x01000) ? 0 : 0x40; command += (data->bits & 0x01000) ? 0 : 0x40;
scancode = system << 8 | command; scancode = system << 8 | command;
IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n", IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
...@@ -204,45 +162,9 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -204,45 +162,9 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
return -EINVAL; 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 = { static struct ir_raw_handler rc5_handler = {
.protocols = IR_TYPE_RC5, .protocols = IR_TYPE_RC5,
.decode = ir_rc5_decode, .decode = ir_rc5_decode,
.raw_register = ir_rc5_register,
.raw_unregister = ir_rc5_unregister,
}; };
static int __init ir_rc5_decode_init(void) static int __init ir_rc5_decode_init(void)
......
...@@ -36,10 +36,6 @@ ...@@ -36,10 +36,6 @@
#define RC6_STARTBIT_MASK 0x08 /* for the header bits */ #define RC6_STARTBIT_MASK 0x08 /* for the header bits */
#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body 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 { enum rc6_mode {
RC6_MODE_0, RC6_MODE_0,
RC6_MODE_6A, RC6_MODE_6A,
...@@ -58,41 +54,8 @@ enum rc6_state { ...@@ -58,41 +54,8 @@ enum rc6_state {
STATE_FINISHED, STATE_FINISHED,
}; };
struct decoder_data { static enum rc6_mode rc6_mode(struct rc6_dec *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)
{ {
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) { switch (data->header & RC6_MODE_MASK) {
case 0: case 0:
return RC6_MODE_0; return RC6_MODE_0;
...@@ -114,15 +77,11 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) { ...@@ -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) 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 ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct rc6_dec *data = &ir_dev->raw->rc6;
u32 scancode; u32 scancode;
u8 toggle; u8 toggle;
data = get_decoder_data(ir_dev);
if (!data)
return -EINVAL;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
return 0; return 0;
...@@ -175,12 +134,11 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -175,12 +134,11 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (ev.pulse) if (ev.pulse)
data->header |= 1; data->header |= 1;
data->count++; data->count++;
data->prev_ev = ev;
data->state = STATE_HEADER_BIT_END; data->state = STATE_HEADER_BIT_END;
return 0; return 0;
case STATE_HEADER_BIT_END: case STATE_HEADER_BIT_END:
if (!is_transition(&ev, &data->prev_ev)) if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break; break;
if (data->count == RC6_HEADER_NBITS) if (data->count == RC6_HEADER_NBITS)
...@@ -196,12 +154,11 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -196,12 +154,11 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
break; break;
data->toggle = ev.pulse; data->toggle = ev.pulse;
data->prev_ev = ev;
data->state = STATE_TOGGLE_END; data->state = STATE_TOGGLE_END;
return 0; return 0;
case STATE_TOGGLE_END: 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)) !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
break; break;
...@@ -211,7 +168,6 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -211,7 +168,6 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
} }
data->state = STATE_BODY_BIT_START; data->state = STATE_BODY_BIT_START;
data->prev_ev = ev;
decrease_duration(&ev, RC6_TOGGLE_END); decrease_duration(&ev, RC6_TOGGLE_END);
data->count = 0; data->count = 0;
...@@ -243,13 +199,11 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -243,13 +199,11 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (ev.pulse) if (ev.pulse)
data->body |= 1; data->body |= 1;
data->count++; data->count++;
data->prev_ev = ev;
data->state = STATE_BODY_BIT_END; data->state = STATE_BODY_BIT_END;
return 0; return 0;
case STATE_BODY_BIT_END: case STATE_BODY_BIT_END:
if (!is_transition(&ev, &data->prev_ev)) if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break; break;
if (data->count == data->wanted_bits) if (data->count == data->wanted_bits)
...@@ -300,45 +254,9 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -300,45 +254,9 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
return -EINVAL; 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 = { static struct ir_raw_handler rc6_handler = {
.protocols = IR_TYPE_RC6, .protocols = IR_TYPE_RC6,
.decode = ir_rc6_decode, .decode = ir_rc6_decode,
.raw_register = ir_rc6_register,
.raw_unregister = ir_rc6_unregister,
}; };
static int __init ir_rc6_decode_init(void) static int __init ir_rc6_decode_init(void)
......
...@@ -23,10 +23,6 @@ ...@@ -23,10 +23,6 @@
#define SONY_BIT_SPACE (1 * SONY_UNIT) #define SONY_BIT_SPACE (1 * SONY_UNIT)
#define SONY_TRAILER_SPACE (10 * SONY_UNIT) /* minimum */ #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 { enum sony_state {
STATE_INACTIVE, STATE_INACTIVE,
STATE_HEADER_SPACE, STATE_HEADER_SPACE,
...@@ -35,36 +31,6 @@ enum sony_state { ...@@ -35,36 +31,6 @@ enum sony_state {
STATE_FINISHED, 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 * ir_sony_decode() - Decode one Sony pulse or space
* @input_dev: the struct input_dev descriptor of the device * @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) ...@@ -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) 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 ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct sony_dec *data = &ir_dev->raw->sony;
u32 scancode; u32 scancode;
u8 device, subdevice, function; u8 device, subdevice, function;
data = get_decoder_data(ir_dev);
if (!data)
return -EINVAL;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
return 0; return 0;
...@@ -124,9 +86,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -124,9 +86,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!ev.pulse) if (!ev.pulse)
break; break;
data->sony_bits <<= 1; data->bits <<= 1;
if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2)) 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)) else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
break; break;
...@@ -160,19 +122,19 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -160,19 +122,19 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
switch (data->count) { switch (data->count) {
case 12: case 12:
device = bitrev8((data->sony_bits << 3) & 0xF8); device = bitrev8((data->bits << 3) & 0xF8);
subdevice = 0; subdevice = 0;
function = bitrev8((data->sony_bits >> 4) & 0xFE); function = bitrev8((data->bits >> 4) & 0xFE);
break; break;
case 15: case 15:
device = bitrev8((data->sony_bits >> 0) & 0xFF); device = bitrev8((data->bits >> 0) & 0xFF);
subdevice = 0; subdevice = 0;
function = bitrev8((data->sony_bits >> 7) & 0xFD); function = bitrev8((data->bits >> 7) & 0xFD);
break; break;
case 20: case 20:
device = bitrev8((data->sony_bits >> 5) & 0xF8); device = bitrev8((data->bits >> 5) & 0xF8);
subdevice = bitrev8((data->sony_bits >> 0) & 0xFF); subdevice = bitrev8((data->bits >> 0) & 0xFF);
function = bitrev8((data->sony_bits >> 12) & 0xFE); function = bitrev8((data->bits >> 12) & 0xFE);
break; break;
default: default:
IR_dprintk(1, "Sony invalid bitcount %u\n", data->count); IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
...@@ -193,45 +155,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev) ...@@ -193,45 +155,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
return -EINVAL; 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 = { static struct ir_raw_handler sony_handler = {
.protocols = IR_TYPE_SONY, .protocols = IR_TYPE_SONY,
.decode = ir_sony_decode, .decode = ir_sony_decode,
.raw_register = ir_sony_register,
.raw_unregister = ir_sony_unregister,
}; };
static int __init ir_sony_decode_init(void) static int __init ir_sony_decode_init(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment