diff options
author | Ricardo Cerqueira <devnull@localhost> | 2006-03-26 03:14:42 +0100 |
---|---|---|
committer | Ricardo Cerqueira <devnull@localhost> | 2006-03-26 03:14:42 +0100 |
commit | eef209698fa363311251b4e0be6f874f837d3da3 (patch) | |
tree | a9376d67095c99583088cdabf6e2c231d2decc58 | |
parent | afb2abb44347c884e3a8a2ddf7151756c1869d2f (diff) | |
download | mediapointer-dvb-s2-eef209698fa363311251b4e0be6f874f837d3da3.tar.gz mediapointer-dvb-s2-eef209698fa363311251b4e0be6f874f837d3da3.tar.bz2 |
Subject: Pinnacle PCTV grey remote control support
From: Sylvain Pasche <sylvain.pasche@gmail.com>
This adds support for the older (?) Pinnacle PCTV remotes (with all buttons
colored in grey). There's no autodetection for the type of remote, though;
saa7134 defaults to the colored one, to use the grey remote the
"pinnacle_remote=1" option must be passed to the saa7134 module
Signed-off-by: Sylvain Pasche <sylvain.pasche@gmail.com>
Signed-off-by: Ricardo Cerqueira <v4l@cerqueira.org>
-rw-r--r-- | linux/drivers/media/common/ir-keymaps.c | 8 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-input.c | 6 | ||||
-rw-r--r-- | linux/drivers/media/video/ir-kbd-i2c.c | 60 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-input.c | 13 | ||||
-rw-r--r-- | linux/include/media/ir-common.h | 4 | ||||
-rw-r--r-- | linux/include/media/ir-kbd-i2c.h | 3 |
6 files changed, 67 insertions, 27 deletions
diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index 03c4a7c50..1ecb0c7a9 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -619,7 +619,7 @@ IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { EXPORT_SYMBOL_GPL(ir_codes_em_terratec); -IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { +IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { [ 0x3a ] = KEY_0, [ 0x31 ] = KEY_1, [ 0x32 ] = KEY_2, @@ -671,7 +671,7 @@ IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { [ 0x27 ] = KEY_RECORD, }; -EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb); +EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { [ 0x0f ] = KEY_0, @@ -1354,7 +1354,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { EXPORT_SYMBOL_GPL(ir_codes_winfast); -IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { +IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE] = { [ 0x59 ] = KEY_MUTE, [ 0x4a ] = KEY_POWER, @@ -1412,7 +1412,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { [ 0x0a ] = KEY_BACKSPACE, }; -EXPORT_SYMBOL_GPL(ir_codes_pinnacle); +EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color); /* Hauppauge: the newer, gray remotes (seems there are multiple * slightly different versions), shipped with cx88+ivtv cards. diff --git a/linux/drivers/media/video/em28xx/em28xx-input.c b/linux/drivers/media/video/em28xx/em28xx-input.c index a8d3cd4b0..1af8bd764 100644 --- a/linux/drivers/media/video/em28xx/em28xx-input.c +++ b/linux/drivers/media/video/em28xx/em28xx-input.c @@ -111,7 +111,7 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } -static int get_key_pinnacle_usb(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +static int get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) { unsigned char buf[3]; @@ -154,8 +154,8 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); break; case (EM2820_BOARD_PINNACLE_USB_2): - ir->ir_codes = ir_codes_em_pinnacle_usb; - ir->get_key = get_key_pinnacle_usb; + ir->ir_codes = ir_codes_pinnacle_grey; + ir->get_key = get_key_pinnacle_usb_grey; snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)"); break; case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index ab1c47648..45a08ced9 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -152,12 +152,11 @@ 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) +/* Common (grey or coloured) pinnacle PCTV remote handling * - * Ricardo Cerqueira <v4l@cerqueira.org> */ - -int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, + int parity_offset, int marker, int code_modulo) { unsigned char b[4]; unsigned int start = 0,parity = 0,code = 0; @@ -169,9 +168,9 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) } for (start = 0; start<4; start++) { - if (b[start] == 0x80) { - code=b[(start+3)%4]; - parity=b[(start+2)%4]; + if (b[start] == marker) { + code=b[(start+parity_offset+1)%4]; + parity=b[(start+parity_offset)%4]; } } @@ -183,16 +182,14 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 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 - */ + /* drop special codes when a key is held down a long time for the grey controller + In this case, the second bit of the code is asserted */ + if (marker == 0xfe && (code & 0x40)) + return 0; - code %= 0x88; + code %= code_modulo; *ir_raw = code; *ir_key = code; @@ -202,7 +199,40 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } -EXPORT_SYMBOL_GPL(get_key_pinnacle); +/* The grey pinnacle PCTV remote + * + * There are one issue with this remote: + * - I2c packet does not change when the same key is pressed quickly. The workaround + * is to hold down each key for about half a second, so that another code is generated + * in the i2c packet, and the function can distinguish key presses. + * + * Sylvain Pasche <sylvain.pasche@gmail.com> + */ +int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + + return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff); +} + +EXPORT_SYMBOL_GPL(get_key_pinnacle_grey); + + +/* The new pinnacle PCTV remote (with the colored buttons) + * + * Ricardo Cerqueira <v4l@cerqueira.org> + */ +int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE + * + * this is the only value that results in 42 unique + * codes < 128 + */ + + return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88); +} + +EXPORT_SYMBOL_GPL(get_key_pinnacle_color); /* ----------------------------------------------------------------------- */ diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c index 0543788bf..a29f94f12 100644 --- a/linux/drivers/media/video/saa7134/saa7134-input.c +++ b/linux/drivers/media/video/saa7134/saa7134-input.c @@ -39,6 +39,10 @@ static unsigned int ir_debug = 0; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); +static int pinnacle_remote = 0; +module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ +MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); + #define dprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) #define i2cdprintk(fmt, arg...) if (ir_debug) \ @@ -324,8 +328,13 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) switch (dev->board) { case SAA7134_BOARD_PINNACLE_PCTV_110i: snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); - ir->get_key = get_key_pinnacle; - ir->ir_codes = ir_codes_pinnacle; + if (pinnacle_remote == 0) { + ir->get_key = get_key_pinnacle_color; + ir->ir_codes = ir_codes_pinnacle_color; + } else { + ir->get_key = get_key_pinnacle_grey; + ir->ir_codes = ir_codes_pinnacle_grey; + } break; case SAA7134_BOARD_UPMOST_PURPLE_TV: snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); diff --git a/linux/include/media/ir-common.h b/linux/include/media/ir-common.h index 8a2e4c640..bee527e44 100644 --- a/linux/include/media/ir-common.h +++ b/linux/include/media/ir-common.h @@ -74,7 +74,7 @@ extern IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE]; @@ -88,7 +88,7 @@ extern IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; #endif diff --git a/linux/include/media/ir-kbd-i2c.h b/linux/include/media/ir-kbd-i2c.h index 730f21ed9..a455f7ce5 100644 --- a/linux/include/media/ir-kbd-i2c.h +++ b/linux/include/media/ir-kbd-i2c.h @@ -20,5 +20,6 @@ struct IR_i2c { int (*get_key)(struct IR_i2c*, u32*, u32*); }; -int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); +int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); +int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); #endif |