From e93854da880d6dc357c00625d8371b6a926fd19b Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Date: Mon, 14 Dec 2009 00:16:55 -0300
Subject: [PATCH] V4L/DVB (13634): ir-core: allow passing IR device parameters
 to ir-core

Adds an structure to ir_input_register to contain IR device characteristics,
like supported protocols and a callback to handle protocol event changes.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/IR/ir-functions.c             |  2 +-
 drivers/media/IR/ir-keytable.c              |  9 +++++++--
 drivers/media/dvb/dm1105/dm1105.c           |  4 ++--
 drivers/media/dvb/mantis/mantis_input.c     |  2 +-
 drivers/media/dvb/ttpci/budget-ci.c         |  2 +-
 drivers/media/video/bt8xx/bttv-input.c      |  4 ++--
 drivers/media/video/cx231xx/cx231xx-input.c |  2 +-
 drivers/media/video/cx23885/cx23885-input.c |  2 +-
 drivers/media/video/cx88/cx88-input.c       |  4 ++--
 drivers/media/video/em28xx/em28xx-input.c   |  2 +-
 drivers/media/video/ir-kbd-i2c.c            |  4 ++--
 drivers/media/video/saa7134/saa7134-input.c |  4 ++--
 include/media/ir-common.h                   |  4 ++--
 include/media/ir-core.h                     | 18 +++++++++++++-----
 include/media/ir-kbd-i2c.h                  |  2 +-
 15 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c
index 776a136616d6..b501ac9d401d 100644
--- a/drivers/media/IR/ir-functions.c
+++ b/drivers/media/IR/ir-functions.c
@@ -52,7 +52,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
 /* -------------------------------------------------------------------------- */
 
 int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-		   int ir_type)
+		  const enum ir_type ir_type)
 {
 	ir->ir_type = ir_type;
 
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index 8097561ec66f..b2d498c3183a 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -89,6 +89,8 @@ EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
  * @origin:	origin table
  *
  * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
+ * Also copies table size and table protocol.
+ * NOTE: It shouldn't copy the lock field
  */
 
 int ir_copy_table(struct ir_scancode_table *destin,
@@ -105,6 +107,7 @@ int ir_copy_table(struct ir_scancode_table *destin,
 		j++;
 	}
 	destin->size = j;
+	destin->ir_type = origin->ir_type;
 
 	IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
 
@@ -404,7 +407,8 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
  * It should be called before registering the IR device.
  */
 int ir_input_register(struct input_dev *input_dev,
-		      struct ir_scancode_table *rc_tab)
+		      const struct ir_scancode_table *rc_tab,
+		      const struct ir_dev_props *props)
 {
 	struct ir_input_dev *ir_dev;
 	struct ir_scancode  *keymap    = rc_tab->scan;
@@ -417,7 +421,7 @@ int ir_input_register(struct input_dev *input_dev,
 	if (!ir_dev)
 		return -ENOMEM;
 
-	spin_lock_init(&rc_tab->lock);
+	spin_lock_init(&ir_dev->rc_tab.lock);
 
 	ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size);
 	ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size *
@@ -430,6 +434,7 @@ int ir_input_register(struct input_dev *input_dev,
 		ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan));
 
 	ir_copy_table(&ir_dev->rc_tab, rc_tab);
+	ir_dev->props = props;
 
 	/* set the bits for the keys */
 	IR_dprintk(1, "key map size: %d\n", rc_tab->size);
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index f0f483ac8b89..414d3b2444a2 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -578,7 +578,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
 {
 	struct input_dev *input_dev;
 	struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table;
-	int ir_type = IR_TYPE_OTHER;
+	enum ir_type ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
 	input_dev = input_allocate_device();
@@ -611,7 +611,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
 
 	INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
 
-	err = ir_input_register(input_dev, ir_codes);
+	err = ir_input_register(input_dev, ir_codes, NULL);
 
 	return err;
 }
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
index 6a9df779441f..4675a3b53c7d 100644
--- a/drivers/media/dvb/mantis/mantis_input.c
+++ b/drivers/media/dvb/mantis/mantis_input.c
@@ -126,7 +126,7 @@ int mantis_input_init(struct mantis_pci *mantis)
 	rc->id.version	= 1;
 	rc->dev		= mantis->pdev->dev;
 
-	err = ir_input_register(rc, &ir_mantis);
+	err = ir_input_register(rc, &ir_mantis, NULL);
 	if (err) {
 		dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
 		input_free_device(rc);
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 9782e0593733..49c2a817a06f 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -254,7 +254,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
 	budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
 	budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
 	budget_ci->ir.last_raw = 0xffff; /* An impossible value */
-	error = ir_input_register(input_dev, ir_codes);
+	error = ir_input_register(input_dev, ir_codes, NULL);
 	if (error) {
 		printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
 		return error;
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index 277a092e1214..f8053fd88346 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -247,7 +247,7 @@ int bttv_input_init(struct bttv *btv)
 	struct card_ir *ir;
 	struct ir_scancode_table *ir_codes = NULL;
 	struct input_dev *input_dev;
-	int ir_type = IR_TYPE_OTHER;
+	enum ir_type ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
 	if (!btv->has_remote)
@@ -389,7 +389,7 @@ int bttv_input_init(struct bttv *btv)
 	bttv_ir_start(btv, ir);
 
 	/* all done */
-	err = ir_input_register(btv->remote->dev, ir_codes);
+	err = ir_input_register(btv->remote->dev, ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 15826f98b688..c5771db3bfce 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -216,7 +216,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
 	cx231xx_ir_start(ir);
 
 	/* all done */
-	err = ir_input_register(ir->input, dev->board.ir_codes);
+	err = ir_input_register(ir->input, dev->board.ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 768eec92ccf9..9c6620f86dca 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -397,7 +397,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
 	dev->ir_input = ir;
 	cx23885_input_ir_start(dev);
 
-	ret = ir_input_register(ir->dev, ir_codes);
+	ret = ir_input_register(ir->dev, ir_codes, NULL);
 	if (ret)
 		goto err_out_stop;
 
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index f9fda18b410c..49c07535e754 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -192,7 +192,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 	struct cx88_IR *ir;
 	struct input_dev *input_dev;
 	struct ir_scancode_table *ir_codes = NULL;
-	int ir_type = IR_TYPE_OTHER;
+	enum ir_type ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
 	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
@@ -383,7 +383,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 	cx88_ir_start(core, ir);
 
 	/* all done */
-	err = ir_input_register(ir->input, ir_codes);
+	err = ir_input_register(ir->input, ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index af0d935c29be..fbfbab6841cd 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -412,7 +412,7 @@ int em28xx_ir_init(struct em28xx *dev)
 	em28xx_ir_start(ir);
 
 	/* all done */
-	err = ir_input_register(ir->input, dev->board.ir_codes);
+	err = ir_input_register(ir->input, dev->board.ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index b86e35386cee..4cd75a3c47d1 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -299,7 +299,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct ir_scancode_table *ir_codes = NULL;
 	const char *name = NULL;
-	int ir_type = 0;
+	enum ir_type ir_type = 0;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
 	struct i2c_adapter *adap = client->adapter;
@@ -446,7 +446,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	input_dev->name       = ir->name;
 	input_dev->phys       = ir->phys;
 
-	err = ir_input_register(ir->input, ir->ir_codes);
+	err = ir_input_register(ir->input, ir->ir_codes, NULL);
 	if (err)
 		goto err_out_free;
 
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index f8e985989ca0..71b4b01824ac 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -460,7 +460,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	int polling      = 0;
 	int rc5_gpio	 = 0;
 	int nec_gpio	 = 0;
-	int ir_type      = IR_TYPE_OTHER;
+	enum ir_type ir_type = IR_TYPE_OTHER;
 	int err;
 
 	if (dev->has_remote != SAA7134_REMOTE_GPIO)
@@ -728,7 +728,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	dev->remote = ir;
 	saa7134_ir_start(dev, ir);
 
-	err = ir_input_register(ir->dev, ir_codes);
+	err = ir_input_register(ir->dev, ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 2c6af24b905e..1b43b772165a 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -35,7 +35,7 @@
 
 struct ir_input_state {
 	/* configuration */
-	int                ir_type;
+	enum ir_type       ir_type;
 
 	/* key info */
 	u32                ir_key;      /* ir scancode */
@@ -84,7 +84,7 @@ struct card_ir {
 /* Routines from ir-functions.c */
 
 int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-		   int ir_type);
+		   const enum ir_type ir_type);
 void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir);
 void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
 		      u32 ir_key);
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index a5a3bda354de..dbdffd1458fb 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -23,10 +23,10 @@ extern int ir_core_debug;
 
 enum ir_type {
 	IR_TYPE_UNKNOWN	= 0,
-	IR_TYPE_RC5	= 1,
-	IR_TYPE_PD	= 2,		 /* Pulse distance encoded IR */
-	IR_TYPE_NEC	= 3,
-	IR_TYPE_OTHER	= 99,
+	IR_TYPE_RC5	= 1L << 0,	/* Philips RC5 protocol */
+	IR_TYPE_PD	= 1L << 1,	/* Pulse distance encoded IR */
+	IR_TYPE_NEC	= 1L << 2,
+	IR_TYPE_OTHER	= 1L << 63,
 };
 
 struct ir_scancode {
@@ -41,12 +41,19 @@ struct ir_scancode_table {
 	spinlock_t		lock;
 };
 
+struct ir_dev_props {
+	unsigned long allowed_protos;
+	void 		*priv;
+	int (*change_protocol)(void *priv, unsigned long protocol);
+};
+
 struct ir_input_dev {
 	struct input_dev		*dev;		/* Input device*/
 	struct ir_scancode_table	rc_tab;		/* scan/key table */
 	unsigned long			devno;		/* device number */
 	struct attribute_group		attr;		/* IR attributes */
 	struct device			*class_dev;	/* virtual class dev */
+	const struct ir_dev_props	*props;		/* Device properties */
 };
 
 /* Routines from ir-keytable.c */
@@ -59,7 +66,8 @@ int ir_set_keycode_table(struct input_dev *input_dev,
 
 int ir_roundup_tablesize(int n_elems);
 int ir_input_register(struct input_dev *dev,
-		      struct ir_scancode_table *ir_codes);
+		      const struct ir_scancode_table *ir_codes,
+		      const struct ir_dev_props *props);
 void ir_input_unregister(struct input_dev *input_dev);
 
 /* Routines from ir-sysfs.c */
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index aaf65e8b1a40..45926e3559f3 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -36,7 +36,7 @@ enum ir_kbd_get_key_fn {
 struct IR_i2c_init_data {
 	struct ir_scancode_table *ir_codes;
 	const char             *name;
-	int                    type; /* IR_TYPE_RC5, IR_TYPE_PD, etc */
+	enum ir_type           type; /* IR_TYPE_RC5, IR_TYPE_PD, etc */
 	/*
 	 * Specify either a function pointer or a value indicating one of
 	 * ir_kbd_i2c's internal get_key functions
-- 
GitLab