diff options
Diffstat (limited to 'drivers/media/video/ir-kbd-i2c.c')
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 0085567a142..740e543311a 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -40,6 +40,7 @@ #include <linux/i2c.h> #include <linux/workqueue.h> #include <asm/semaphore.h> + #include <media/ir-common.h> #include <media/ir-kbd-i2c.h> @@ -183,6 +184,58 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } +/* The new pinnacle PCTV remote (with the colored buttons) + * + * Ricardo Cerqueira <v4l@cerqueira.org> + */ + +int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char b[4]; + unsigned int start = 0,parity = 0,code = 0; + + /* poll IR chip */ + if (4 != i2c_master_recv(&ir->c,b,4)) { + dprintk(2,"read error\n"); + return -EIO; + } + + for (start = 0; start<4; start++) { + if (b[start] == 0x80) { + code=b[(start+3)%4]; + parity=b[(start+2)%4]; + } + } + + /* Empty Request */ + if (parity==0) + return 0; + + /* Repeating... */ + if (ir->old == parity) + return 0; + + + ir->old = parity; + + /* Reduce code value to fit inside IR_KEYTAB_SIZE + * + * this is the only value that results in 42 unique + * codes < 128 + */ + + code %= 0x88; + + *ir_raw = code; + *ir_key = code; + + dprintk(1,"Pinnacle PCTV key %02x\n", code); + + return 1; +} + +EXPORT_SYMBOL_GPL(get_key_pinnacle); + /* ----------------------------------------------------------------------- */ static void ir_key_poll(struct IR_i2c *ir) @@ -226,7 +279,7 @@ static int ir_probe(struct i2c_adapter *adap); static struct i2c_driver driver = { .name = "ir remote kbd driver", - .id = I2C_DRIVERID_EXP3, /* FIXME */ + .id = I2C_DRIVERID_INFRARED, .flags = I2C_DF_NOTIFY, .attach_adapter = ir_probe, .detach_client = ir_detach, @@ -244,15 +297,15 @@ static int ir_attach(struct i2c_adapter *adap, int addr, IR_KEYTAB_TYPE *ir_codes = NULL; char *name; int ir_type; - struct IR_i2c *ir; + struct IR_i2c *ir; struct input_dev *input_dev; - ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL); + ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); input_dev = input_allocate_device(); if (!ir || !input_dev) { kfree(ir); input_free_device(input_dev); - return -ENOMEM; + return -ENOMEM; } ir->c = client_template; @@ -308,7 +361,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, /* register i2c device * At device register, IR codes may be changed to be * board dependent. - */ + */ i2c_attach_client(&ir->c); /* If IR not supported or disabled, unregisters driver */ |