diff options
author | Sylvain Pasche <sylvain.pasche@gmail.com> | 2006-03-25 21:14:42 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-25 01:00:28 -0400 |
commit | b93eedb62e358588c5e595b07fb85efa1f597a9f (patch) | |
tree | ec3ffd9ccd6136d752efa1dbea9235dbd85ed7f8 /drivers | |
parent | e48a9c6283c1ca2565167f0b4bce4d0be7f49fae (diff) |
V4L/DVB (4023): Subject: Pinnacle PCTV grey remote control support
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>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/common/ir-keymaps.c | 8 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-input.c | 6 | ||||
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 60 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 13 |
4 files changed, 63 insertions, 24 deletions
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index fab97f46f325..8f4a067afdb7 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c | |||
@@ -618,7 +618,7 @@ IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { | |||
618 | 618 | ||
619 | EXPORT_SYMBOL_GPL(ir_codes_em_terratec); | 619 | EXPORT_SYMBOL_GPL(ir_codes_em_terratec); |
620 | 620 | ||
621 | IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { | 621 | IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { |
622 | [ 0x3a ] = KEY_0, | 622 | [ 0x3a ] = KEY_0, |
623 | [ 0x31 ] = KEY_1, | 623 | [ 0x31 ] = KEY_1, |
624 | [ 0x32 ] = KEY_2, | 624 | [ 0x32 ] = KEY_2, |
@@ -670,7 +670,7 @@ IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { | |||
670 | [ 0x27 ] = KEY_RECORD, | 670 | [ 0x27 ] = KEY_RECORD, |
671 | }; | 671 | }; |
672 | 672 | ||
673 | EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb); | 673 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); |
674 | 674 | ||
675 | IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { | 675 | IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { |
676 | [ 0x0f ] = KEY_0, | 676 | [ 0x0f ] = KEY_0, |
@@ -1290,7 +1290,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
1290 | 1290 | ||
1291 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | 1291 | EXPORT_SYMBOL_GPL(ir_codes_winfast); |
1292 | 1292 | ||
1293 | IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | 1293 | IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE] = { |
1294 | [ 0x59 ] = KEY_MUTE, | 1294 | [ 0x59 ] = KEY_MUTE, |
1295 | [ 0x4a ] = KEY_POWER, | 1295 | [ 0x4a ] = KEY_POWER, |
1296 | 1296 | ||
@@ -1348,7 +1348,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | |||
1348 | [ 0x0a ] = KEY_BACKSPACE, | 1348 | [ 0x0a ] = KEY_BACKSPACE, |
1349 | }; | 1349 | }; |
1350 | 1350 | ||
1351 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle); | 1351 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color); |
1352 | 1352 | ||
1353 | /* Hauppauge: the newer, gray remotes (seems there are multiple | 1353 | /* Hauppauge: the newer, gray remotes (seems there are multiple |
1354 | * slightly different versions), shipped with cx88+ivtv cards. | 1354 | * slightly different versions), shipped with cx88+ivtv cards. |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 86aff371a287..3ffb5684f127 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -105,7 +105,7 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
105 | return 1; | 105 | return 1; |
106 | } | 106 | } |
107 | 107 | ||
108 | static int get_key_pinnacle_usb(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 108 | static int get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
109 | { | 109 | { |
110 | unsigned char buf[3]; | 110 | unsigned char buf[3]; |
111 | 111 | ||
@@ -148,8 +148,8 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) | |||
148 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); | 148 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); |
149 | break; | 149 | break; |
150 | case (EM2820_BOARD_PINNACLE_USB_2): | 150 | case (EM2820_BOARD_PINNACLE_USB_2): |
151 | ir->ir_codes = ir_codes_em_pinnacle_usb; | 151 | ir->ir_codes = ir_codes_pinnacle_grey; |
152 | ir->get_key = get_key_pinnacle_usb; | 152 | ir->get_key = get_key_pinnacle_usb_grey; |
153 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)"); | 153 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)"); |
154 | break; | 154 | break; |
155 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): | 155 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 7e66d83fe0ce..fba30a40e9c6 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -150,12 +150,11 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
150 | return 1; | 150 | return 1; |
151 | } | 151 | } |
152 | 152 | ||
153 | /* The new pinnacle PCTV remote (with the colored buttons) | 153 | /* Common (grey or coloured) pinnacle PCTV remote handling |
154 | * | 154 | * |
155 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
156 | */ | 155 | */ |
157 | 156 | static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, | |
158 | int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 157 | int parity_offset, int marker, int code_modulo) |
159 | { | 158 | { |
160 | unsigned char b[4]; | 159 | unsigned char b[4]; |
161 | unsigned int start = 0,parity = 0,code = 0; | 160 | unsigned int start = 0,parity = 0,code = 0; |
@@ -167,9 +166,9 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
167 | } | 166 | } |
168 | 167 | ||
169 | for (start = 0; start<4; start++) { | 168 | for (start = 0; start<4; start++) { |
170 | if (b[start] == 0x80) { | 169 | if (b[start] == marker) { |
171 | code=b[(start+3)%4]; | 170 | code=b[(start+parity_offset+1)%4]; |
172 | parity=b[(start+2)%4]; | 171 | parity=b[(start+parity_offset)%4]; |
173 | } | 172 | } |
174 | } | 173 | } |
175 | 174 | ||
@@ -181,16 +180,14 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
181 | if (ir->old == parity) | 180 | if (ir->old == parity) |
182 | return 0; | 181 | return 0; |
183 | 182 | ||
184 | |||
185 | ir->old = parity; | 183 | ir->old = parity; |
186 | 184 | ||
187 | /* Reduce code value to fit inside IR_KEYTAB_SIZE | 185 | /* drop special codes when a key is held down a long time for the grey controller |
188 | * | 186 | In this case, the second bit of the code is asserted */ |
189 | * this is the only value that results in 42 unique | 187 | if (marker == 0xfe && (code & 0x40)) |
190 | * codes < 128 | 188 | return 0; |
191 | */ | ||
192 | 189 | ||
193 | code %= 0x88; | 190 | code %= code_modulo; |
194 | 191 | ||
195 | *ir_raw = code; | 192 | *ir_raw = code; |
196 | *ir_key = code; | 193 | *ir_key = code; |
@@ -200,7 +197,40 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
200 | return 1; | 197 | return 1; |
201 | } | 198 | } |
202 | 199 | ||
203 | EXPORT_SYMBOL_GPL(get_key_pinnacle); | 200 | /* The grey pinnacle PCTV remote |
201 | * | ||
202 | * There are one issue with this remote: | ||
203 | * - I2c packet does not change when the same key is pressed quickly. The workaround | ||
204 | * is to hold down each key for about half a second, so that another code is generated | ||
205 | * in the i2c packet, and the function can distinguish key presses. | ||
206 | * | ||
207 | * Sylvain Pasche <sylvain.pasche@gmail.com> | ||
208 | */ | ||
209 | int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
210 | { | ||
211 | |||
212 | return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff); | ||
213 | } | ||
214 | |||
215 | EXPORT_SYMBOL_GPL(get_key_pinnacle_grey); | ||
216 | |||
217 | |||
218 | /* The new pinnacle PCTV remote (with the colored buttons) | ||
219 | * | ||
220 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
221 | */ | ||
222 | int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
223 | { | ||
224 | /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE | ||
225 | * | ||
226 | * this is the only value that results in 42 unique | ||
227 | * codes < 128 | ||
228 | */ | ||
229 | |||
230 | return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88); | ||
231 | } | ||
232 | |||
233 | EXPORT_SYMBOL_GPL(get_key_pinnacle_color); | ||
204 | 234 | ||
205 | /* ----------------------------------------------------------------------- */ | 235 | /* ----------------------------------------------------------------------- */ |
206 | 236 | ||
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 1426e4c8602f..7c595492c56b 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -37,6 +37,10 @@ static unsigned int ir_debug = 0; | |||
37 | module_param(ir_debug, int, 0644); | 37 | module_param(ir_debug, int, 0644); |
38 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | 38 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); |
39 | 39 | ||
40 | static int pinnacle_remote = 0; | ||
41 | module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ | ||
42 | MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); | ||
43 | |||
40 | #define dprintk(fmt, arg...) if (ir_debug) \ | 44 | #define dprintk(fmt, arg...) if (ir_debug) \ |
41 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) | 45 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) |
42 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | 46 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ |
@@ -316,8 +320,13 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) | |||
316 | switch (dev->board) { | 320 | switch (dev->board) { |
317 | case SAA7134_BOARD_PINNACLE_PCTV_110i: | 321 | case SAA7134_BOARD_PINNACLE_PCTV_110i: |
318 | snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); | 322 | snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); |
319 | ir->get_key = get_key_pinnacle; | 323 | if (pinnacle_remote == 0) { |
320 | ir->ir_codes = ir_codes_pinnacle; | 324 | ir->get_key = get_key_pinnacle_color; |
325 | ir->ir_codes = ir_codes_pinnacle_color; | ||
326 | } else { | ||
327 | ir->get_key = get_key_pinnacle_grey; | ||
328 | ir->ir_codes = ir_codes_pinnacle_grey; | ||
329 | } | ||
321 | break; | 330 | break; |
322 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | 331 | case SAA7134_BOARD_UPMOST_PURPLE_TV: |
323 | snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); | 332 | snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); |