Commit 716aab44 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

V4L/DVB: ir-core: Add callbacks for input/evdev open/close on IR core

Especially when IR needs to do polling, it generates lots of wakeups per
second. This makes no sense, if the input event device is closed.

Adds a callback handler to the IR hardware driver, to allow registering
an open/close ops.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e202c15b
...@@ -446,6 +446,19 @@ void ir_keydown(struct input_dev *dev, int scancode) ...@@ -446,6 +446,19 @@ void ir_keydown(struct input_dev *dev, int scancode)
} }
EXPORT_SYMBOL_GPL(ir_keydown); EXPORT_SYMBOL_GPL(ir_keydown);
static int ir_open(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
return ir_dev->props->open(ir_dev->props->priv);
}
static void ir_close(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
ir_dev->props->close(ir_dev->props->priv);
}
/** /**
* ir_input_register() - sets the IR keycode table and add the handlers * ir_input_register() - sets the IR keycode table and add the handlers
...@@ -495,6 +508,10 @@ int ir_input_register(struct input_dev *input_dev, ...@@ -495,6 +508,10 @@ int ir_input_register(struct input_dev *input_dev,
ir_copy_table(&ir_dev->rc_tab, rc_tab); ir_copy_table(&ir_dev->rc_tab, rc_tab);
ir_dev->props = props; ir_dev->props = props;
if (props && props->open)
input_dev->open = ir_open;
if (props && props->close)
input_dev->close = ir_close;
/* set the bits for the keys */ /* set the bits for the keys */
IR_dprintk(1, "key map size: %d\n", rc_tab->size); IR_dprintk(1, "key map size: %d\n", rc_tab->size);
......
...@@ -1227,7 +1227,7 @@ static int saa7134_resume(struct pci_dev *pci_dev) ...@@ -1227,7 +1227,7 @@ static int saa7134_resume(struct pci_dev *pci_dev)
if (card_has_mpeg(dev)) if (card_has_mpeg(dev))
saa7134_ts_init_hw(dev); saa7134_ts_init_hw(dev);
if (dev->remote) if (dev->remote)
saa7134_ir_start(dev, dev->remote); saa7134_ir_start(dev);
saa7134_hw_enable1(dev); saa7134_hw_enable1(dev);
msleep(100); msleep(100);
......
...@@ -400,7 +400,14 @@ static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) ...@@ -400,7 +400,14 @@ static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
void saa7134_input_irq(struct saa7134_dev *dev) void saa7134_input_irq(struct saa7134_dev *dev)
{ {
struct card_ir *ir = dev->remote; struct card_ir *ir;
if (!dev || !dev->remote)
return;
ir = dev->remote;
if (!ir->running)
return;
if (ir->nec_gpio) { if (ir->nec_gpio) {
saa7134_nec_irq(dev); saa7134_nec_irq(dev);
...@@ -432,10 +439,20 @@ void ir_raw_decode_timer_end(unsigned long data) ...@@ -432,10 +439,20 @@ void ir_raw_decode_timer_end(unsigned long data)
ir->active = 0; ir->active = 0;
} }
void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) static int __saa7134_ir_start(void *priv)
{ {
struct saa7134_dev *dev = priv;
struct card_ir *ir;
if (!dev)
return -EINVAL;
ir = dev->remote;
if (!ir)
return -EINVAL;
if (ir->running) if (ir->running)
return; return 0;
ir->running = 1; ir->running = 1;
if (ir->polling) { if (ir->polling) {
...@@ -467,11 +484,21 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) ...@@ -467,11 +484,21 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
ir->timer_end.data = (unsigned long)dev; ir->timer_end.data = (unsigned long)dev;
ir->active = 0; ir->active = 0;
} }
return 0;
} }
void saa7134_ir_stop(struct saa7134_dev *dev) static void __saa7134_ir_stop(void *priv)
{ {
struct card_ir *ir = dev->remote; struct saa7134_dev *dev = priv;
struct card_ir *ir;
if (!dev)
return;
ir = dev->remote;
if (!ir)
return;
if (!ir->running) if (!ir->running)
return; return;
...@@ -487,8 +514,42 @@ void saa7134_ir_stop(struct saa7134_dev *dev) ...@@ -487,8 +514,42 @@ void saa7134_ir_stop(struct saa7134_dev *dev)
} }
ir->running = 0; ir->running = 0;
return;
}
int saa7134_ir_start(struct saa7134_dev *dev)
{
if (dev->remote->users)
return __saa7134_ir_start(dev);
return 0;
}
void saa7134_ir_stop(struct saa7134_dev *dev)
{
if (dev->remote->users)
__saa7134_ir_stop(dev);
}
static int saa7134_ir_open(void *priv)
{
struct saa7134_dev *dev = priv;
dev->remote->users++;
return __saa7134_ir_start(dev);
} }
static void saa7134_ir_close(void *priv)
{
struct saa7134_dev *dev = priv;
dev->remote->users--;
if (!dev->remote->users)
__saa7134_ir_stop(dev);
}
int saa7134_ir_change_protocol(void *priv, u64 ir_type) int saa7134_ir_change_protocol(void *priv, u64 ir_type)
{ {
struct saa7134_dev *dev = priv; struct saa7134_dev *dev = priv;
...@@ -513,7 +574,7 @@ int saa7134_ir_change_protocol(void *priv, u64 ir_type) ...@@ -513,7 +574,7 @@ int saa7134_ir_change_protocol(void *priv, u64 ir_type)
saa7134_ir_stop(dev); saa7134_ir_stop(dev);
ir->nec_gpio = nec_gpio; ir->nec_gpio = nec_gpio;
ir->rc5_gpio = rc5_gpio; ir->rc5_gpio = rc5_gpio;
saa7134_ir_start(dev, ir); saa7134_ir_start(dev);
} else { } else {
ir->nec_gpio = nec_gpio; ir->nec_gpio = nec_gpio;
ir->rc5_gpio = rc5_gpio; ir->rc5_gpio = rc5_gpio;
...@@ -788,9 +849,13 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -788,9 +849,13 @@ int saa7134_input_init1(struct saa7134_dev *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(dev->pci)); pci_name(dev->pci));
ir->props.priv = dev;
ir->props.open = saa7134_ir_open;
ir->props.close = saa7134_ir_close;
if (ir_codes->ir_type != IR_TYPE_OTHER && !raw_decode) { if (ir_codes->ir_type != IR_TYPE_OTHER && !raw_decode) {
ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
ir->props.priv = dev;
ir->props.change_protocol = saa7134_ir_change_protocol; ir->props.change_protocol = saa7134_ir_change_protocol;
/* Set IR protocol */ /* Set IR protocol */
...@@ -815,25 +880,21 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -815,25 +880,21 @@ int saa7134_input_init1(struct saa7134_dev *dev)
err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME); err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME);
if (err) if (err)
goto err_out_stop; goto err_out_free;
if (ir_codes->ir_type != IR_TYPE_OTHER) { if (ir_codes->ir_type != IR_TYPE_OTHER) {
err = ir_raw_event_register(ir->dev); err = ir_raw_event_register(ir->dev);
if (err) if (err)
goto err_out_stop; goto err_out_free;
} }
saa7134_ir_start(dev, ir);
/* the remote isn't as bouncy as a keyboard */ /* the remote isn't as bouncy as a keyboard */
ir->dev->rep[REP_DELAY] = repeat_delay; ir->dev->rep[REP_DELAY] = repeat_delay;
ir->dev->rep[REP_PERIOD] = repeat_period; ir->dev->rep[REP_PERIOD] = repeat_period;
return 0; return 0;
err_out_stop: err_out_free:
saa7134_ir_stop(dev);
dev->remote = NULL; dev->remote = NULL;
err_out_free:
kfree(ir); kfree(ir);
return err; return err;
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
#include <linux/version.h> #include <linux/version.h>
#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,15) #define SAA7134_VERSION_CODE KERNEL_VERSION(0, 2, 16)
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -810,7 +810,7 @@ int saa7134_input_init1(struct saa7134_dev *dev); ...@@ -810,7 +810,7 @@ int saa7134_input_init1(struct saa7134_dev *dev);
void saa7134_input_fini(struct saa7134_dev *dev); void saa7134_input_fini(struct saa7134_dev *dev);
void saa7134_input_irq(struct saa7134_dev *dev); void saa7134_input_irq(struct saa7134_dev *dev);
void saa7134_probe_i2c_ir(struct saa7134_dev *dev); void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); int saa7134_ir_start(struct saa7134_dev *dev);
void saa7134_ir_stop(struct saa7134_dev *dev); void saa7134_ir_stop(struct saa7134_dev *dev);
......
...@@ -50,6 +50,7 @@ struct card_ir { ...@@ -50,6 +50,7 @@ struct card_ir {
struct ir_input_state ir; struct ir_input_state ir;
char name[32]; char name[32];
char phys[32]; char phys[32];
int users;
u32 running:1; u32 running:1;
struct ir_dev_props props; struct ir_dev_props props;
......
...@@ -56,6 +56,8 @@ struct ir_dev_props { ...@@ -56,6 +56,8 @@ struct ir_dev_props {
unsigned long allowed_protos; unsigned long allowed_protos;
void *priv; void *priv;
int (*change_protocol)(void *priv, u64 ir_type); int (*change_protocol)(void *priv, u64 ir_type);
int (*open)(void *priv);
void (*close)(void *priv);
}; };
struct ir_raw_event { struct ir_raw_event {
......
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