diff options
author | Igor M. Liplianin <liplianin@netup.ru> | 2009-02-26 01:49:44 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:43:00 -0400 |
commit | b72857dd457b96de653b19b3c40394dac6285819 (patch) | |
tree | e9cfbd22366b976d4dd3f95a1cca1210ce67e5c1 /drivers/media/dvb/dm1105 | |
parent | d1498ffc474b18574ed2d5e4d9a33fd21eaaf3cf (diff) |
V4L/DVB (10744): dm1105: infrared remote code is remaked.
The driver infrared remote code part is altered to switch to a work queue.
Also ir_codes table moved to ir-common module for shared access.
Signed-off-by: Igor M. Liplianin <liplianin@netup.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dm1105')
-rw-r--r-- | drivers/media/dvb/dm1105/dm1105.c | 100 |
1 files changed, 17 insertions, 83 deletions
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index d9f55beb4890..5b20cf5a29f0 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c | |||
@@ -156,46 +156,12 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); | |||
156 | 156 | ||
157 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 157 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
158 | 158 | ||
159 | static u16 ir_codes_dm1105_nec[128] = { | ||
160 | [0x0a] = KEY_Q, /*power*/ | ||
161 | [0x0c] = KEY_M, /*mute*/ | ||
162 | [0x11] = KEY_1, | ||
163 | [0x12] = KEY_2, | ||
164 | [0x13] = KEY_3, | ||
165 | [0x14] = KEY_4, | ||
166 | [0x15] = KEY_5, | ||
167 | [0x16] = KEY_6, | ||
168 | [0x17] = KEY_7, | ||
169 | [0x18] = KEY_8, | ||
170 | [0x19] = KEY_9, | ||
171 | [0x10] = KEY_0, | ||
172 | [0x1c] = KEY_PAGEUP, /*ch+*/ | ||
173 | [0x0f] = KEY_PAGEDOWN, /*ch-*/ | ||
174 | [0x1a] = KEY_O, /*vol+*/ | ||
175 | [0x0e] = KEY_Z, /*vol-*/ | ||
176 | [0x04] = KEY_R, /*rec*/ | ||
177 | [0x09] = KEY_D, /*fav*/ | ||
178 | [0x08] = KEY_BACKSPACE, /*rewind*/ | ||
179 | [0x07] = KEY_A, /*fast*/ | ||
180 | [0x0b] = KEY_P, /*pause*/ | ||
181 | [0x02] = KEY_ESC, /*cancel*/ | ||
182 | [0x03] = KEY_G, /*tab*/ | ||
183 | [0x00] = KEY_UP, /*up*/ | ||
184 | [0x1f] = KEY_ENTER, /*ok*/ | ||
185 | [0x01] = KEY_DOWN, /*down*/ | ||
186 | [0x05] = KEY_C, /*cap*/ | ||
187 | [0x06] = KEY_S, /*stop*/ | ||
188 | [0x40] = KEY_F, /*full*/ | ||
189 | [0x1e] = KEY_W, /*tvmode*/ | ||
190 | [0x1b] = KEY_B, /*recall*/ | ||
191 | }; | ||
192 | |||
193 | /* infrared remote control */ | 159 | /* infrared remote control */ |
194 | struct infrared { | 160 | struct infrared { |
195 | u16 key_map[128]; | ||
196 | struct input_dev *input_dev; | 161 | struct input_dev *input_dev; |
162 | struct ir_input_state ir; | ||
197 | char input_phys[32]; | 163 | char input_phys[32]; |
198 | struct tasklet_struct ir_tasklet; | 164 | struct work_struct work; |
199 | u32 ir_command; | 165 | u32 ir_command; |
200 | }; | 166 | }; |
201 | 167 | ||
@@ -237,8 +203,6 @@ struct dm1105dvb { | |||
237 | 203 | ||
238 | #define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) | 204 | #define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) |
239 | 205 | ||
240 | static struct dm1105dvb *dm1105dvb_local; | ||
241 | |||
242 | static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, | 206 | static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, |
243 | struct i2c_msg *msgs, int num) | 207 | struct i2c_msg *msgs, int num) |
244 | { | 208 | { |
@@ -411,31 +375,20 @@ static int dm1105dvb_stop_feed(struct dvb_demux_feed *f) | |||
411 | return 0; | 375 | return 0; |
412 | } | 376 | } |
413 | 377 | ||
414 | /* ir tasklet */ | 378 | /* ir work handler */ |
415 | static void dm1105_emit_key(unsigned long parm) | 379 | static void dm1105_emit_key(struct work_struct *work) |
416 | { | 380 | { |
417 | struct infrared *ir = (struct infrared *) parm; | 381 | struct infrared *ir = container_of(work, struct infrared, work); |
418 | u32 ircom = ir->ir_command; | 382 | u32 ircom = ir->ir_command; |
419 | u8 data; | 383 | u8 data; |
420 | u16 keycode; | ||
421 | 384 | ||
422 | if (ir_debug) | 385 | if (ir_debug) |
423 | printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom); | 386 | printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom); |
424 | 387 | ||
425 | data = (ircom >> 8) & 0x7f; | 388 | data = (ircom >> 8) & 0x7f; |
426 | 389 | ||
427 | input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data); | 390 | ir_input_keydown(ir->input_dev, &ir->ir, data, data); |
428 | input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); | 391 | ir_input_nokey(ir->input_dev, &ir->ir); |
429 | keycode = ir->key_map[data]; | ||
430 | |||
431 | if (!keycode) | ||
432 | return; | ||
433 | |||
434 | input_event(ir->input_dev, EV_KEY, keycode, 1); | ||
435 | input_sync(ir->input_dev); | ||
436 | input_event(ir->input_dev, EV_KEY, keycode, 0); | ||
437 | input_sync(ir->input_dev); | ||
438 | |||
439 | } | 392 | } |
440 | 393 | ||
441 | /* work handler */ | 394 | /* work handler */ |
@@ -491,34 +444,19 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) | |||
491 | break; | 444 | break; |
492 | case INTSTS_IR: | 445 | case INTSTS_IR: |
493 | dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); | 446 | dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); |
494 | tasklet_schedule(&dm1105dvb->ir.ir_tasklet); | 447 | schedule_work(&dm1105dvb->ir.work); |
495 | break; | 448 | break; |
496 | } | 449 | } |
497 | 450 | ||
498 | return IRQ_HANDLED; | 451 | return IRQ_HANDLED; |
499 | } | 452 | } |
500 | 453 | ||
501 | /* register with input layer */ | ||
502 | static void input_register_keys(struct infrared *ir) | ||
503 | { | ||
504 | int i; | ||
505 | |||
506 | memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); | ||
507 | |||
508 | for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) | ||
509 | set_bit(ir->key_map[i], ir->input_dev->keybit); | ||
510 | |||
511 | ir->input_dev->keycode = ir->key_map; | ||
512 | ir->input_dev->keycodesize = sizeof(ir->key_map[0]); | ||
513 | ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); | ||
514 | } | ||
515 | |||
516 | int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | 454 | int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) |
517 | { | 455 | { |
518 | struct input_dev *input_dev; | 456 | struct input_dev *input_dev; |
519 | int err; | 457 | IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec; |
520 | 458 | int ir_type = IR_TYPE_OTHER; | |
521 | dm1105dvb_local = dm1105; | 459 | int err = -ENOMEM; |
522 | 460 | ||
523 | input_dev = input_allocate_device(); | 461 | input_dev = input_allocate_device(); |
524 | if (!input_dev) | 462 | if (!input_dev) |
@@ -528,12 +466,11 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | |||
528 | snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), | 466 | snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), |
529 | "pci-%s/ir0", pci_name(dm1105->pdev)); | 467 | "pci-%s/ir0", pci_name(dm1105->pdev)); |
530 | 468 | ||
531 | input_dev->evbit[0] = BIT(EV_KEY); | 469 | ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes); |
532 | input_dev->name = "DVB on-card IR receiver"; | 470 | input_dev->name = "DVB on-card IR receiver"; |
533 | |||
534 | input_dev->phys = dm1105->ir.input_phys; | 471 | input_dev->phys = dm1105->ir.input_phys; |
535 | input_dev->id.bustype = BUS_PCI; | 472 | input_dev->id.bustype = BUS_PCI; |
536 | input_dev->id.version = 2; | 473 | input_dev->id.version = 1; |
537 | if (dm1105->pdev->subsystem_vendor) { | 474 | if (dm1105->pdev->subsystem_vendor) { |
538 | input_dev->id.vendor = dm1105->pdev->subsystem_vendor; | 475 | input_dev->id.vendor = dm1105->pdev->subsystem_vendor; |
539 | input_dev->id.product = dm1105->pdev->subsystem_device; | 476 | input_dev->id.product = dm1105->pdev->subsystem_device; |
@@ -541,25 +478,22 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | |||
541 | input_dev->id.vendor = dm1105->pdev->vendor; | 478 | input_dev->id.vendor = dm1105->pdev->vendor; |
542 | input_dev->id.product = dm1105->pdev->device; | 479 | input_dev->id.product = dm1105->pdev->device; |
543 | } | 480 | } |
481 | |||
544 | input_dev->dev.parent = &dm1105->pdev->dev; | 482 | input_dev->dev.parent = &dm1105->pdev->dev; |
545 | /* initial keymap */ | 483 | |
546 | memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map); | 484 | INIT_WORK(&dm1105->ir.work, dm1105_emit_key); |
547 | input_register_keys(&dm1105->ir); | 485 | |
548 | err = input_register_device(input_dev); | 486 | err = input_register_device(input_dev); |
549 | if (err) { | 487 | if (err) { |
550 | input_free_device(input_dev); | 488 | input_free_device(input_dev); |
551 | return err; | 489 | return err; |
552 | } | 490 | } |
553 | 491 | ||
554 | tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir); | ||
555 | |||
556 | return 0; | 492 | return 0; |
557 | } | 493 | } |
558 | 494 | ||
559 | |||
560 | void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) | 495 | void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) |
561 | { | 496 | { |
562 | tasklet_kill(&dm1105->ir.ir_tasklet); | ||
563 | input_unregister_device(dm1105->ir.input_dev); | 497 | input_unregister_device(dm1105->ir.input_dev); |
564 | 498 | ||
565 | } | 499 | } |