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

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
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -446,6 +446,19 @@ void ir_keydown(struct input_dev *dev, int scancode)
}
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
@@ -495,6 +508,10 @@ int ir_input_register(struct input_dev *input_dev,

	ir_copy_table(&ir_dev->rc_tab, rc_tab);
	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 */
	IR_dprintk(1, "key map size: %d\n", rc_tab->size);
+1 −1
Original line number Diff line number Diff line
@@ -1227,7 +1227,7 @@ static int saa7134_resume(struct pci_dev *pci_dev)
	if (card_has_mpeg(dev))
		saa7134_ts_init_hw(dev);
	if (dev->remote)
		saa7134_ir_start(dev, dev->remote);
		saa7134_ir_start(dev);
	saa7134_hw_enable1(dev);

	msleep(100);
+75 −14
Original line number Diff line number Diff line
@@ -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)
{
	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) {
		saa7134_nec_irq(dev);
@@ -432,10 +439,20 @@ void ir_raw_decode_timer_end(unsigned long data)
	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)
		return;
		return 0;

	ir->running = 1;
	if (ir->polling) {
@@ -467,11 +484,21 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
		ir->timer_end.data = (unsigned long)dev;
		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)
		return;
@@ -487,8 +514,42 @@ void saa7134_ir_stop(struct saa7134_dev *dev)
	}

	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)
{
	struct saa7134_dev *dev = priv;
@@ -513,7 +574,7 @@ int saa7134_ir_change_protocol(void *priv, u64 ir_type)
		saa7134_ir_stop(dev);
		ir->nec_gpio = nec_gpio;
		ir->rc5_gpio = rc5_gpio;
		saa7134_ir_start(dev, ir);
		saa7134_ir_start(dev);
	} else {
		ir->nec_gpio = nec_gpio;
		ir->rc5_gpio = rc5_gpio;
@@ -788,9 +849,13 @@ int saa7134_input_init1(struct saa7134_dev *dev)
	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
		 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) {
		ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
		ir->props.priv = dev;
		ir->props.change_protocol = saa7134_ir_change_protocol;

		/* Set IR protocol */
@@ -815,25 +880,21 @@ int saa7134_input_init1(struct saa7134_dev *dev)

	err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME);
	if (err)
		goto err_out_stop;
		goto err_out_free;
	if (ir_codes->ir_type != IR_TYPE_OTHER) {
		err = ir_raw_event_register(ir->dev);
		if (err)
			goto err_out_stop;
			goto err_out_free;
	}

	saa7134_ir_start(dev, ir);

	/* the remote isn't as bouncy as a keyboard */
	ir->dev->rep[REP_DELAY] = repeat_delay;
	ir->dev->rep[REP_PERIOD] = repeat_period;

	return 0;

 err_out_stop:
	saa7134_ir_stop(dev);
	dev->remote = NULL;
err_out_free:
	dev->remote = NULL;
	kfree(ir);
	return err;
}
+2 −2
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
 */

#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/i2c.h>
@@ -810,7 +810,7 @@ int saa7134_input_init1(struct saa7134_dev *dev);
void saa7134_input_fini(struct saa7134_dev *dev);
void saa7134_input_irq(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);


+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ struct card_ir {
	struct ir_input_state   ir;
	char                    name[32];
	char                    phys[32];
	int			users;

	u32			running:1;
	struct ir_dev_props	props;
Loading