aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c58
-rw-r--r--drivers/media/usb/em28xx/em28xx-reg.h1
2 files changed, 39 insertions, 20 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 660bf803c9e4..507370c5217d 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -57,8 +57,8 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
57struct em28xx_ir_poll_result { 57struct em28xx_ir_poll_result {
58 unsigned int toggle_bit:1; 58 unsigned int toggle_bit:1;
59 unsigned int read_count:7; 59 unsigned int read_count:7;
60 u8 rc_address; 60
61 u8 rc_data[4]; /* 1 byte on em2860/2880, 4 on em2874 */ 61 u32 scancode;
62}; 62};
63 63
64struct em28xx_IR { 64struct em28xx_IR {
@@ -72,6 +72,7 @@ struct em28xx_IR {
72 struct delayed_work work; 72 struct delayed_work work;
73 unsigned int full_code:1; 73 unsigned int full_code:1;
74 unsigned int last_readcount; 74 unsigned int last_readcount;
75 u64 rc_type;
75 76
76 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); 77 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
77}; 78};
@@ -236,11 +237,8 @@ static int default_polling_getkey(struct em28xx_IR *ir,
236 /* Infrared read count (Reg 0x45[6:0] */ 237 /* Infrared read count (Reg 0x45[6:0] */
237 poll_result->read_count = (msg[0] & 0x7f); 238 poll_result->read_count = (msg[0] & 0x7f);
238 239
239 /* Remote Control Address (Reg 0x46) */ 240 /* Remote Control Address/Data (Regs 0x46/0x47) */
240 poll_result->rc_address = msg[1]; 241 poll_result->scancode = msg[1] << 8 | msg[2];
241
242 /* Remote Control Data (Reg 0x47) */
243 poll_result->rc_data[0] = msg[2];
244 242
245 return 0; 243 return 0;
246} 244}
@@ -266,13 +264,32 @@ static int em2874_polling_getkey(struct em28xx_IR *ir,
266 /* Infrared read count (Reg 0x51[6:0] */ 264 /* Infrared read count (Reg 0x51[6:0] */
267 poll_result->read_count = (msg[0] & 0x7f); 265 poll_result->read_count = (msg[0] & 0x7f);
268 266
269 /* Remote Control Address (Reg 0x52) */ 267 /*
270 poll_result->rc_address = msg[1]; 268 * Remote Control Address (Reg 0x52)
271 269 * Remote Control Data (Reg 0x53-0x55)
272 /* Remote Control Data (Reg 0x53-55) */ 270 */
273 poll_result->rc_data[0] = msg[2]; 271 switch (ir->rc_type) {
274 poll_result->rc_data[1] = msg[3]; 272 case RC_BIT_RC5:
275 poll_result->rc_data[2] = msg[4]; 273 poll_result->scancode = msg[1] << 8 | msg[2];
274 break;
275 case RC_BIT_NEC:
276 if ((msg[3] ^ msg[4]) != 0xff) /* 32 bits NEC */
277 poll_result->scancode = (msg[1] << 24) |
278 (msg[2] << 16) |
279 (msg[3] << 8) |
280 msg[4];
281 else if ((msg[1] ^ msg[2]) != 0xff) /* 24 bits NEC */
282 poll_result->scancode = (msg[1] << 16) |
283 (msg[2] << 8) |
284 msg[3];
285 else /* Normal NEC */
286 poll_result->scancode = msg[1] << 8 | msg[3];
287 break;
288 default:
289 poll_result->scancode = (msg[1] << 24) | (msg[2] << 16) |
290 (msg[3] << 8) | msg[4];
291 break;
292 }
276 293
277 return 0; 294 return 0;
278} 295}
@@ -294,17 +311,16 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
294 } 311 }
295 312
296 if (unlikely(poll_result.read_count != ir->last_readcount)) { 313 if (unlikely(poll_result.read_count != ir->last_readcount)) {
297 dprintk("%s: toggle: %d, count: %d, key 0x%02x%02x\n", __func__, 314 dprintk("%s: toggle: %d, count: %d, key 0x%04x\n", __func__,
298 poll_result.toggle_bit, poll_result.read_count, 315 poll_result.toggle_bit, poll_result.read_count,
299 poll_result.rc_address, poll_result.rc_data[0]); 316 poll_result.scancode);
300 if (ir->full_code) 317 if (ir->full_code)
301 rc_keydown(ir->rc, 318 rc_keydown(ir->rc,
302 poll_result.rc_address << 8 | 319 poll_result.scancode,
303 poll_result.rc_data[0],
304 poll_result.toggle_bit); 320 poll_result.toggle_bit);
305 else 321 else
306 rc_keydown(ir->rc, 322 rc_keydown(ir->rc,
307 poll_result.rc_data[0], 323 poll_result.scancode & 0xff,
308 poll_result.toggle_bit); 324 poll_result.toggle_bit);
309 325
310 if (ir->dev->chip_id == CHIP_ID_EM2874 || 326 if (ir->dev->chip_id == CHIP_ID_EM2874 ||
@@ -360,12 +376,14 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
360 *rc_type = RC_BIT_RC5; 376 *rc_type = RC_BIT_RC5;
361 } else if (*rc_type & RC_BIT_NEC) { 377 } else if (*rc_type & RC_BIT_NEC) {
362 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; 378 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
363 ir_config = EM2874_IR_NEC; 379 ir_config = EM2874_IR_NEC | EM2874_IR_NEC_NO_PARITY;
364 ir->full_code = 1; 380 ir->full_code = 1;
365 *rc_type = RC_BIT_NEC; 381 *rc_type = RC_BIT_NEC;
366 } else if (*rc_type != RC_BIT_UNKNOWN) 382 } else if (*rc_type != RC_BIT_UNKNOWN)
367 rc = -EINVAL; 383 rc = -EINVAL;
368 384
385 ir->rc_type = *rc_type;
386
369 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, 387 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
370 EM28XX_XCLK_IR_RC5_MODE); 388 EM28XX_XCLK_IR_RC5_MODE);
371 389
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 6ff368297f6e..2ad357354d81 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -177,6 +177,7 @@
177 177
178/* em2874 IR config register (0x50) */ 178/* em2874 IR config register (0x50) */
179#define EM2874_IR_NEC 0x00 179#define EM2874_IR_NEC 0x00
180#define EM2874_IR_NEC_NO_PARITY 0x01
180#define EM2874_IR_RC5 0x04 181#define EM2874_IR_RC5 0x04
181#define EM2874_IR_RC6_MODE_0 0x08 182#define EM2874_IR_RC6_MODE_0 0x08
182#define EM2874_IR_RC6_MODE_6A 0x0b 183#define EM2874_IR_RC6_MODE_6A 0x0b