📄 saa7134-input.c
字号:
polling = 50; // ms /* Set GPIO pin2 to high to enable the IR controller */ saa_setb(SAA7134_GPIO_GPMODE0, 0x4); saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); break; case SAA7134_BOARD_AVERMEDIA_M135A: ir_codes = ir_codes_avermedia_m135a; mask_keydown = 0x0040000; mask_keycode = 0x00013f; nec_gpio = 1; break; case SAA7134_BOARD_AVERMEDIA_777: case SAA7134_BOARD_AVERMEDIA_A16AR: ir_codes = ir_codes_avermedia; mask_keycode = 0x02F200; mask_keydown = 0x000400; polling = 50; // ms /* Without this we won't receive key up events */ saa_setb(SAA7134_GPIO_GPMODE1, 0x1); saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); break; case SAA7134_BOARD_AVERMEDIA_A16D: ir_codes = ir_codes_avermedia_a16d; mask_keycode = 0x02F200; mask_keydown = 0x000400; polling = 50; /* ms */ /* Without this we won't receive key up events */ saa_setb(SAA7134_GPIO_GPMODE1, 0x1); saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); break; case SAA7134_BOARD_KWORLD_TERMINATOR: ir_codes = ir_codes_pixelview; mask_keycode = 0x00001f; mask_keyup = 0x000060; polling = 50; // ms break; case SAA7134_BOARD_MANLI_MTV001: case SAA7134_BOARD_MANLI_MTV002: ir_codes = ir_codes_manli; mask_keycode = 0x001f00; mask_keyup = 0x004000; polling = 50; /* ms */ break; case SAA7134_BOARD_BEHOLD_409FM: case SAA7134_BOARD_BEHOLD_401: case SAA7134_BOARD_BEHOLD_403: case SAA7134_BOARD_BEHOLD_403FM: case SAA7134_BOARD_BEHOLD_405: case SAA7134_BOARD_BEHOLD_405FM: case SAA7134_BOARD_BEHOLD_407: case SAA7134_BOARD_BEHOLD_407FM: case SAA7134_BOARD_BEHOLD_409: case SAA7134_BOARD_BEHOLD_505FM: case SAA7134_BOARD_BEHOLD_507_9FM: ir_codes = ir_codes_manli; mask_keycode = 0x003f00; mask_keyup = 0x004000; polling = 50; /* ms */ break; case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: ir_codes = ir_codes_behold_columbus; mask_keycode = 0x003f00; mask_keyup = 0x004000; polling = 50; // ms break; case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: ir_codes = ir_codes_pctv_sedna; mask_keycode = 0x001f00; mask_keyup = 0x004000; polling = 50; // ms break; case SAA7134_BOARD_GOTVIEW_7135: ir_codes = ir_codes_gotview7135; mask_keycode = 0x0003CC; mask_keydown = 0x000010; polling = 5; /* ms */ saa_setb(SAA7134_GPIO_GPMODE1, 0x80); break; case SAA7134_BOARD_VIDEOMATE_TV_PVR: case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: ir_codes = ir_codes_videomate_tv_pvr; mask_keycode = 0x00003F; mask_keyup = 0x400000; polling = 50; // ms break; case SAA7134_BOARD_PROTEUS_2309: ir_codes = ir_codes_proteus_2309; mask_keycode = 0x00007F; mask_keyup = 0x000080; polling = 50; // ms break; case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_VIDEOMATE_DVBT_200: ir_codes = ir_codes_videomate_tv_pvr; mask_keycode = 0x003F00; mask_keyup = 0x040000; break; case SAA7134_BOARD_FLYDVBS_LR300: case SAA7134_BOARD_FLYDVBT_LR301: case SAA7134_BOARD_FLYDVBTDUO: ir_codes = ir_codes_flydvb; mask_keycode = 0x0001F00; mask_keydown = 0x0040000; break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: ir_codes = ir_codes_asus_pc39; mask_keydown = 0x0040000; rc5_gpio = 1; break; case SAA7134_BOARD_ENCORE_ENLTV: case SAA7134_BOARD_ENCORE_ENLTV_FM: ir_codes = ir_codes_encore_enltv; mask_keycode = 0x00007f; mask_keyup = 0x040000; polling = 50; // ms break; case SAA7134_BOARD_ENCORE_ENLTV_FM53: ir_codes = ir_codes_encore_enltv_fm53; mask_keydown = 0x0040000; mask_keycode = 0x00007f; nec_gpio = 1; break; case SAA7134_BOARD_10MOONSTVMASTER3: ir_codes = ir_codes_encore_enltv; mask_keycode = 0x5f80000; mask_keyup = 0x8000000; polling = 50; //ms break; case SAA7134_BOARD_GENIUS_TVGO_A11MCE: ir_codes = ir_codes_genius_tvgo_a11mce; mask_keycode = 0xff; mask_keydown = 0xf00000; polling = 50; /* ms */ break; case SAA7134_BOARD_REAL_ANGEL_220: ir_codes = ir_codes_real_audio_220_32_keys; mask_keycode = 0x3f00; mask_keyup = 0x4000; polling = 50; /* ms */ break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", dev->name, dev->board); return -ENODEV; } ir = kzalloc(sizeof(*ir), GFP_KERNEL); input_dev = input_allocate_device(); if (!ir || !input_dev) { err = -ENOMEM; goto err_out_free; } ir->dev = input_dev; /* init hardware-specific stuff */ ir->mask_keycode = mask_keycode; ir->mask_keydown = mask_keydown; ir->mask_keyup = mask_keyup; ir->polling = polling; ir->rc5_gpio = rc5_gpio; ir->nec_gpio = nec_gpio; /* init input device */ snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", saa7134_boards[dev->board].name); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; input_dev->id.version = 1; if (dev->pci->subsystem_vendor) { input_dev->id.vendor = dev->pci->subsystem_vendor; input_dev->id.product = dev->pci->subsystem_device; } else { input_dev->id.vendor = dev->pci->vendor; input_dev->id.product = dev->pci->device; }#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) input_dev->dev.parent = &dev->pci->dev;#else input_dev->cdev.dev = &dev->pci->dev;#endif dev->remote = ir; saa7134_ir_start(dev, ir); err = input_register_device(ir->dev); if (err) goto err_out_stop; /* the remote isn't as bouncy as a keyboard */ ir->dev->rep[REP_DELAY] = repeat_delay; ir->dev->rep[REP_PERIOD] = repeat_period; return 0; err_out_stop: saa7134_ir_stop(dev); dev->remote = NULL; err_out_free: input_free_device(input_dev); kfree(ir); return err;}void saa7134_input_fini(struct saa7134_dev *dev){ if (NULL == dev->remote) return; saa7134_ir_stop(dev); input_unregister_device(dev->remote->dev); kfree(dev->remote); dev->remote = NULL;}void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir){ if (disable_ir) { dprintk("Found supported i2c remote, but IR has been disabled\n"); ir->get_key=NULL; return; } switch (dev->board) { case SAA7134_BOARD_PINNACLE_PCTV_110i: case SAA7134_BOARD_PINNACLE_PCTV_310i: snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); 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"); ir->get_key = get_key_purpletv; ir->ir_codes = ir_codes_purpletv; break; case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus"); ir->get_key = get_key_msi_tvanywhere_plus; ir->ir_codes = ir_codes_msi_tvanywhere_plus; break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); ir->get_key = get_key_hvr1110; ir->ir_codes = ir_codes_hauppauge_new; break; case SAA7134_BOARD_BEHOLD_607_9FM: case SAA7134_BOARD_BEHOLD_M6: case SAA7134_BOARD_BEHOLD_M63: case SAA7134_BOARD_BEHOLD_M6_EXTRA: case SAA7134_BOARD_BEHOLD_H6: snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); ir->get_key = get_key_beholdm6xx; ir->ir_codes = ir_codes_behold; break; default: dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); break; }}static int saa7134_rc5_irq(struct saa7134_dev *dev){ struct card_ir *ir = dev->remote; struct timeval tv; u32 gap; unsigned long current_jiffies, timeout; /* get time of bit */ current_jiffies = jiffies; do_gettimeofday(&tv); /* avoid overflow with gap >1s */ if (tv.tv_sec - ir->base_time.tv_sec > 1) { gap = 200000; } else { gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + tv.tv_usec - ir->base_time.tv_usec; } /* active code => add bit */ if (ir->active) { /* only if in the code (otherwise spurious IRQ or timer late) */ if (ir->last_bit < 28) { ir->last_bit = (gap - ir_rc5_remote_gap / 2) / ir_rc5_remote_gap; ir->code |= 1 << ir->last_bit; } /* starting new code */ } else { ir->active = 1; ir->code = 0; ir->base_time = tv; ir->last_bit = 0; timeout = current_jiffies + (500 + 30 * HZ) / 1000; mod_timer(&ir->timer_end, timeout); } return 1;}/* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms The first pulse (start) has 9 + 4.5 ms */static void saa7134_nec_timer(unsigned long data){ struct saa7134_dev *dev = (struct saa7134_dev *) data; struct card_ir *ir = dev->remote; dprintk("Cancel key repeat\n"); ir_input_nokey(ir->dev, &ir->ir);}static void nec_task(unsigned long data){ struct saa7134_dev *dev = (struct saa7134_dev *) data; struct card_ir *ir; struct timeval tv; int count, pulse, oldpulse, gap; u32 ircode = 0, not_code = 0; int ngap = 0; if (!data) { printk(KERN_ERR "saa713x/ir: Can't recover dev struct\n"); /* GPIO will be kept disabled */ return; } ir = dev->remote; /* rising SAA7134_GPIO_GPRESCAN reads the status */ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); oldpulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; pulse = oldpulse; do_gettimeofday(&tv); ir->base_time = tv; /* Decode NEC pulsecode. This code can take up to 76.5 ms to run. Unfortunately, using IRQ to decode pulse didn't work, since it uses a pulse train of 38KHz. This means one pulse on each 52 us */ do { /* Wait until the end of pulse/space or 5 ms */ for (count = 0; count < 500; count++) { udelay(10); /* rising SAA7134_GPIO_GPRESCAN reads the status */ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; if (pulse != oldpulse) break; } do_gettimeofday(&tv); gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + tv.tv_usec - ir->base_time.tv_usec; if (!pulse) {#if 0 if (!ngap && gap < 4000) break;#endif /* Bit 0 has 560 us, while bit 1 has 1120 us. Do something only if bit == 1 */ if (ngap && (gap > 560 + 280)) { unsigned int shift = ngap - 1; /* Address first, then command */ if (shift < 8) { shift += 8; ircode |= 1 << shift; } else if (shift < 16) { not_code |= 1 << shift; } else if (shift < 24) { shift -= 16; ircode |= 1 << shift; } else { shift -= 24; not_code |= 1 << shift; } } ngap++; } ir->base_time = tv; /* TIMEOUT - Long pulse */ if (gap >= 5000) break; oldpulse = pulse; } while (ngap < 32); if (ngap == 32) { /* FIXME: should check if not_code == ~ircode */ ir->code = ir_extract_bits(ircode, ir->mask_keycode); dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n", ir->code, ircode, not_code); ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code); } else dprintk("Repeat last key\n"); /* Keep repeating the last key */ mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150)); saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18);}static int saa7134_nec_irq(struct saa7134_dev *dev){ struct card_ir *ir = dev->remote; saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); tasklet_schedule(&ir->tlet); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -