📄 saa7134-input.c
字号:
[ 0x13 ] = KEY_MUTE, [ 0x19 ] = KEY_RECORD, /*XXX*/ // 0x1d unused ?};/* Mike Baikov <mike@baikov.com> */static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = { [ 33 ] = KEY_POWER, [ 105] = KEY_TV, [ 51 ] = KEY_KP0, [ 81 ] = KEY_KP1, [ 49 ] = KEY_KP2, [ 113] = KEY_KP3, [ 59 ] = KEY_KP4, [ 88 ] = KEY_KP5, [ 65 ] = KEY_KP6, [ 72 ] = KEY_KP7, [ 48 ] = KEY_KP8, [ 83 ] = KEY_KP9, [ 115] = KEY_AGAIN, /* LOOP */ [ 10 ] = KEY_AUDIO, [ 97 ] = KEY_PRINT, /* PREVIEW */ [ 122] = KEY_VIDEO, [ 32 ] = KEY_CHANNELUP, [ 64 ] = KEY_CHANNELDOWN, [ 24 ] = KEY_VOLUMEDOWN, [ 80 ] = KEY_VOLUMEUP, [ 16 ] = KEY_MUTE, [ 74 ] = KEY_SEARCH, [ 123] = KEY_SHUFFLE, /* SNAPSHOT */ [ 34 ] = KEY_RECORD, [ 98 ] = KEY_STOP, [ 120] = KEY_PLAY, [ 57 ] = KEY_REWIND, [ 89 ] = KEY_PAUSE, [ 25 ] = KEY_FORWARD, [ 9 ] = KEY_ZOOM, [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */ [ 26 ] = KEY_F22, /* MIN TIMESHIFT */ [ 58 ] = KEY_F23, /* TIMESHIFT */ [ 112] = KEY_F24, /* NORMAL TIMESHIFT */};static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { [ 0x3 ] = KEY_POWER, [ 0x6f ] = KEY_MUTE, [ 0x10 ] = KEY_BACKSPACE, /* Recall */ [ 0x11 ] = KEY_KP0, [ 0x4 ] = KEY_KP1, [ 0x5 ] = KEY_KP2, [ 0x6 ] = KEY_KP3, [ 0x8 ] = KEY_KP4, [ 0x9 ] = KEY_KP5, [ 0xa ] = KEY_KP6, [ 0xc ] = KEY_KP7, [ 0xd ] = KEY_KP8, [ 0xe ] = KEY_KP9, [ 0x12 ] = KEY_KPDOT, /* 100+ */ [ 0x7 ] = KEY_VOLUMEUP, [ 0xb ] = KEY_VOLUMEDOWN, [ 0x1a ] = KEY_KPPLUS, [ 0x18 ] = KEY_KPMINUS, [ 0x15 ] = KEY_UP, [ 0x1d ] = KEY_DOWN, [ 0xf ] = KEY_CHANNELUP, [ 0x13 ] = KEY_CHANNELDOWN, [ 0x48 ] = KEY_ZOOM, [ 0x1b ] = KEY_VIDEO, /* Video source */ [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ [ 0x4b ] = KEY_RECORD, [ 0x46 ] = KEY_PLAY, [ 0x45 ] = KEY_PAUSE, /* Pause */ [ 0x44 ] = KEY_STOP, [ 0x40 ] = KEY_FORWARD, /* Forward ? */ [ 0x42 ] = KEY_REWIND, /* Backward ? */};/* Mapping for the 28 key remote control as seen at http://www.sednacomputer.com/photo/cardbus-tv.jpg Pavel Mihaylov <bin@bash.info> */static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = { [ 0 ] = KEY_KP0, [ 1 ] = KEY_KP1, [ 2 ] = KEY_KP2, [ 3 ] = KEY_KP3, [ 4 ] = KEY_KP4, [ 5 ] = KEY_KP5, [ 6 ] = KEY_KP6, [ 7 ] = KEY_KP7, [ 8 ] = KEY_KP8, [ 9 ] = KEY_KP9, [ 0x0a ] = KEY_AGAIN, /* Recall */ [ 0x0b ] = KEY_CHANNELUP, [ 0x0c ] = KEY_VOLUMEUP, [ 0x0d ] = KEY_MODE, /* Stereo */ [ 0x0e ] = KEY_STOP, [ 0x0f ] = KEY_PREVIOUSSONG, [ 0x10 ] = KEY_ZOOM, [ 0x11 ] = KEY_TUNER, /* Source */ [ 0x12 ] = KEY_POWER, [ 0x13 ] = KEY_MUTE, [ 0x15 ] = KEY_CHANNELDOWN, [ 0x18 ] = KEY_VOLUMEDOWN, [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */ [ 0x1a ] = KEY_NEXTSONG, [ 0x1b ] = KEY_TEXT, /* Time Shift */ [ 0x1c ] = KEY_RADIO, /* FM Radio */ [ 0x1d ] = KEY_RECORD, [ 0x1e ] = KEY_PAUSE,};/* -------------------- GPIO generic keycode builder -------------------- */static int build_key(struct saa7134_dev *dev){ struct saa7134_ir *ir = dev->remote; u32 gpio, data; /* rising SAA7134_GPIO_GPRESCAN reads the status */ saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); if (ir->polling) { if (ir->last_gpio == gpio) return 0; ir->last_gpio = gpio; } data = ir_extract_bits(gpio, ir->mask_keycode); dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", gpio, ir->mask_keycode, data); if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { ir_input_keydown(ir->dev, &ir->ir, data, data); } else { ir_input_nokey(ir->dev, &ir->ir); } return 0;}/* --------------------- Chip specific I2C key builders ----------------- */static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw){ unsigned char b; /* poll IR chip */ if (1 != i2c_master_recv(&ir->c,&b,1)) { i2cdprintk("read error\n"); return -EIO; } /* no button press */ if (b==0) return 0; /* repeating */ if (b & 0x80) return 1; *ir_key = b; *ir_raw = b; return 1;}void saa7134_input_irq(struct saa7134_dev *dev){ struct saa7134_ir *ir = dev->remote; if (!ir->polling) build_key(dev);}static void saa7134_input_timer(unsigned long data){ struct saa7134_dev *dev = (struct saa7134_dev*)data; struct saa7134_ir *ir = dev->remote; unsigned long timeout; build_key(dev); timeout = jiffies + (ir->polling * HZ / 1000); mod_timer(&ir->timer, timeout);}int saa7134_input_init1(struct saa7134_dev *dev){ struct saa7134_ir *ir; struct input_dev *input_dev; IR_KEYTAB_TYPE *ir_codes = NULL; u32 mask_keycode = 0; u32 mask_keydown = 0; u32 mask_keyup = 0; int polling = 0; int ir_type = IR_TYPE_OTHER; if (dev->has_remote != SAA7134_REMOTE_GPIO) return -ENODEV; if (disable_ir) return -ENODEV; /* detect & configure */ switch (dev->board) { case SAA7134_BOARD_FLYVIDEO2000: case SAA7134_BOARD_FLYVIDEO3000: case SAA7134_BOARD_FLYTVPLATINUM_FM: case SAA7134_BOARD_FLYTVPLATINUM_MINI2: ir_codes = flyvideo_codes; mask_keycode = 0xEC00000; mask_keydown = 0x0040000; break; case SAA7134_BOARD_CINERGY400: case SAA7134_BOARD_CINERGY600: case SAA7134_BOARD_CINERGY600_MK3: ir_codes = cinergy_codes; mask_keycode = 0x00003f; mask_keyup = 0x040000; break; case SAA7134_BOARD_ECS_TVP3XP: case SAA7134_BOARD_ECS_TVP3XP_4CB5: ir_codes = eztv_codes; mask_keycode = 0x00017c; mask_keyup = 0x000002; polling = 50; // ms break; case SAA7134_BOARD_KWORLD_XPERT: case SAA7134_BOARD_AVACSSMARTTV: ir_codes = avacssmart_codes; mask_keycode = 0x00001F; mask_keyup = 0x000020; polling = 50; // ms break; case SAA7134_BOARD_MD2819: case SAA7134_BOARD_KWORLD_VSTREAM_XPERT: case SAA7134_BOARD_AVERMEDIA_305: case SAA7134_BOARD_AVERMEDIA_307: case SAA7134_BOARD_AVERMEDIA_STUDIO_305: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: ir_codes = md2819_codes; mask_keycode = 0x0007C8; mask_keydown = 0x000010; 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_KWORLD_TERMINATOR: ir_codes = avacssmart_codes; mask_keycode = 0x00001f; mask_keyup = 0x000060; polling = 50; // ms break; case SAA7134_BOARD_MANLI_MTV001: case SAA7134_BOARD_MANLI_MTV002: case SAA7134_BOARD_BEHOLD_409FM: ir_codes = manli_codes; mask_keycode = 0x001f00; mask_keyup = 0x004000; polling = 50; // ms break; case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: ir_codes = pctv_sedna_codes; mask_keycode = 0x001f00; mask_keyup = 0x004000; polling = 50; // ms break; case SAA7134_BOARD_GOTVIEW_7135: ir_codes = gotview7135_codes; mask_keycode = 0x0003EC; mask_keyup = 0x008000; mask_keydown = 0x000010; polling = 50; // ms break; case SAA7134_BOARD_VIDEOMATE_TV_PVR: case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: ir_codes = videomate_tv_pvr_codes; mask_keycode = 0x00003F; mask_keyup = 0x400000; polling = 50; // ms break; case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_VIDEOMATE_DVBT_200: ir_codes = videomate_tv_pvr_codes; mask_keycode = 0x003F00; mask_keyup = 0x040000; 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) { kfree(ir); input_free_device(input_dev); return -ENOMEM; } 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; /* 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; } input_dev->cdev.dev = &dev->pci->dev; /* all done */ dev->remote = ir; if (ir->polling) { init_timer(&ir->timer); ir->timer.function = saa7134_input_timer; ir->timer.data = (unsigned long)dev; ir->timer.expires = jiffies + HZ; add_timer(&ir->timer); } input_register_device(ir->dev); return 0;}void saa7134_input_fini(struct saa7134_dev *dev){ if (NULL == dev->remote) return; if (dev->remote->polling) del_timer_sync(&dev->remote->timer); 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: snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); ir->get_key = get_key_pinnacle; ir->ir_codes = ir_codes_pinnacle; 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; default: dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); break; }}/* ---------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -