diff options
author | David S. Miller <davem@davemloft.net> | 2010-02-28 22:23:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-28 22:23:06 -0500 |
commit | 47871889c601d8199c51a4086f77eebd77c29b0b (patch) | |
tree | 40cdcac3bff0ee40cc33dcca61d0577cdf965f77 /drivers/media/video/em28xx/em28xx-input.c | |
parent | c16cc0b464b8876cfd57ce1c1dbcb6f9a6a0bce3 (diff) | |
parent | 30ff056c42c665b9ea535d8515890857ae382540 (diff) |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts:
drivers/firmware/iscsi_ibft.c
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-input.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-input.c | 113 |
1 files changed, 87 insertions, 26 deletions
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index af0d935c29b..1fb754e2087 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -75,6 +75,10 @@ struct em28xx_IR { | |||
75 | unsigned int repeat_interval; | 75 | unsigned int repeat_interval; |
76 | 76 | ||
77 | int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); | 77 | int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); |
78 | |||
79 | /* IR device properties */ | ||
80 | |||
81 | struct ir_dev_props props; | ||
78 | }; | 82 | }; |
79 | 83 | ||
80 | /********************************************************** | 84 | /********************************************************** |
@@ -180,6 +184,36 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | |||
180 | return 1; | 184 | return 1; |
181 | } | 185 | } |
182 | 186 | ||
187 | int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
188 | { | ||
189 | unsigned char subaddr, keydetect, key; | ||
190 | |||
191 | struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1}, | ||
192 | |||
193 | { .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} }; | ||
194 | |||
195 | subaddr = 0x10; | ||
196 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { | ||
197 | i2cdprintk("read error\n"); | ||
198 | return -EIO; | ||
199 | } | ||
200 | if (keydetect == 0x00) | ||
201 | return 0; | ||
202 | |||
203 | subaddr = 0x00; | ||
204 | msg[1].buf = &key; | ||
205 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { | ||
206 | i2cdprintk("read error\n"); | ||
207 | return -EIO; | ||
208 | } | ||
209 | if (key == 0x00) | ||
210 | return 0; | ||
211 | |||
212 | *ir_key = key; | ||
213 | *ir_raw = key; | ||
214 | return 1; | ||
215 | } | ||
216 | |||
183 | /********************************************************** | 217 | /********************************************************** |
184 | Poll based get keycode functions | 218 | Poll based get keycode functions |
185 | **********************************************************/ | 219 | **********************************************************/ |
@@ -336,35 +370,28 @@ static void em28xx_ir_stop(struct em28xx_IR *ir) | |||
336 | cancel_delayed_work_sync(&ir->work); | 370 | cancel_delayed_work_sync(&ir->work); |
337 | } | 371 | } |
338 | 372 | ||
339 | int em28xx_ir_init(struct em28xx *dev) | 373 | int em28xx_ir_change_protocol(void *priv, u64 ir_type) |
340 | { | 374 | { |
341 | struct em28xx_IR *ir; | 375 | int rc = 0; |
342 | struct input_dev *input_dev; | 376 | struct em28xx_IR *ir = priv; |
343 | u8 ir_config; | 377 | struct em28xx *dev = ir->dev; |
344 | int err = -ENOMEM; | 378 | u8 ir_config = EM2874_IR_RC5; |
345 | |||
346 | if (dev->board.ir_codes == NULL) { | ||
347 | /* No remote control support */ | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | ||
352 | input_dev = input_allocate_device(); | ||
353 | if (!ir || !input_dev) | ||
354 | goto err_out_free; | ||
355 | |||
356 | ir->input = input_dev; | ||
357 | ir_config = EM2874_IR_RC5; | ||
358 | 379 | ||
359 | /* Adjust xclk based o IR table for RC5/NEC tables */ | 380 | /* Adjust xclk based o IR table for RC5/NEC tables */ |
360 | if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) { | 381 | |
382 | dev->board.ir_codes->ir_type = IR_TYPE_OTHER; | ||
383 | if (ir_type == IR_TYPE_RC5) { | ||
361 | dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; | 384 | dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; |
362 | ir->full_code = 1; | 385 | ir->full_code = 1; |
363 | } else if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) { | 386 | } else if (ir_type == IR_TYPE_NEC) { |
364 | dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; | 387 | dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; |
365 | ir_config = EM2874_IR_NEC; | 388 | ir_config = EM2874_IR_NEC; |
366 | ir->full_code = 1; | 389 | ir->full_code = 1; |
367 | } | 390 | } else |
391 | rc = -EINVAL; | ||
392 | |||
393 | dev->board.ir_codes->ir_type = ir_type; | ||
394 | |||
368 | em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, | 395 | em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, |
369 | EM28XX_XCLK_IR_RC5_MODE); | 396 | EM28XX_XCLK_IR_RC5_MODE); |
370 | 397 | ||
@@ -380,9 +407,42 @@ int em28xx_ir_init(struct em28xx *dev) | |||
380 | break; | 407 | break; |
381 | default: | 408 | default: |
382 | printk("Unrecognized em28xx chip id: IR not supported\n"); | 409 | printk("Unrecognized em28xx chip id: IR not supported\n"); |
383 | goto err_out_free; | 410 | rc = -EINVAL; |
411 | } | ||
412 | |||
413 | return rc; | ||
414 | } | ||
415 | |||
416 | int em28xx_ir_init(struct em28xx *dev) | ||
417 | { | ||
418 | struct em28xx_IR *ir; | ||
419 | struct input_dev *input_dev; | ||
420 | int err = -ENOMEM; | ||
421 | |||
422 | if (dev->board.ir_codes == NULL) { | ||
423 | /* No remote control support */ | ||
424 | return 0; | ||
384 | } | 425 | } |
385 | 426 | ||
427 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | ||
428 | input_dev = input_allocate_device(); | ||
429 | if (!ir || !input_dev) | ||
430 | goto err_out_free; | ||
431 | |||
432 | /* record handles to ourself */ | ||
433 | ir->dev = dev; | ||
434 | dev->ir = ir; | ||
435 | |||
436 | ir->input = input_dev; | ||
437 | |||
438 | /* | ||
439 | * em2874 supports more protocols. For now, let's just announce | ||
440 | * the two protocols that were already tested | ||
441 | */ | ||
442 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; | ||
443 | ir->props.priv = ir; | ||
444 | ir->props.change_protocol = em28xx_ir_change_protocol; | ||
445 | |||
386 | /* This is how often we ask the chip for IR information */ | 446 | /* This is how often we ask the chip for IR information */ |
387 | ir->polling = 100; /* ms */ | 447 | ir->polling = 100; /* ms */ |
388 | 448 | ||
@@ -393,6 +453,8 @@ int em28xx_ir_init(struct em28xx *dev) | |||
393 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); | 453 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); |
394 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | 454 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); |
395 | 455 | ||
456 | /* Set IR protocol */ | ||
457 | em28xx_ir_change_protocol(ir, dev->board.ir_codes->ir_type); | ||
396 | err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); | 458 | err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); |
397 | if (err < 0) | 459 | if (err < 0) |
398 | goto err_out_free; | 460 | goto err_out_free; |
@@ -405,14 +467,13 @@ int em28xx_ir_init(struct em28xx *dev) | |||
405 | input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); | 467 | input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); |
406 | 468 | ||
407 | input_dev->dev.parent = &dev->udev->dev; | 469 | input_dev->dev.parent = &dev->udev->dev; |
408 | /* record handles to ourself */ | 470 | |
409 | ir->dev = dev; | ||
410 | dev->ir = ir; | ||
411 | 471 | ||
412 | em28xx_ir_start(ir); | 472 | em28xx_ir_start(ir); |
413 | 473 | ||
414 | /* all done */ | 474 | /* all done */ |
415 | err = ir_input_register(ir->input, dev->board.ir_codes); | 475 | err = ir_input_register(ir->input, dev->board.ir_codes, |
476 | &ir->props); | ||
416 | if (err) | 477 | if (err) |
417 | goto err_out_stop; | 478 | goto err_out_stop; |
418 | 479 | ||