diff options
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-input.c')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 403 |
1 files changed, 353 insertions, 50 deletions
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 242cb235cf92..329accda6d45 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -39,6 +39,8 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); #define dprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) +#define i2cdprintk(fmt, arg...) if (ir_debug) \ + printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) /* ---------------------------------------------------------------------- */ @@ -114,24 +116,24 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { /* Alfons Geser <a.geser@cox.net> * updates from Job D. R. Borges <jobdrb@ig.com.br> */ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { - [ 18 ] = KEY_POWER, - [ 1 ] = KEY_TV, // DVR - [ 21 ] = KEY_DVD, // DVD - [ 23 ] = KEY_AUDIO, // music - // DVR mode / DVD mode / music mode - - [ 27 ] = KEY_MUTE, // mute - [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek - [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek - [ 22 ] = KEY_ZOOM, // full screen - [ 28 ] = KEY_VIDEO, // video source / eject / delall - [ 29 ] = KEY_RESTART, // playback / angle / del - [ 47 ] = KEY_SEARCH, // scan / menu / playlist - [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo - - [ 49 ] = KEY_HELP, // help - [ 50 ] = KEY_MODE, // num/memo - [ 51 ] = KEY_ESC, // cancel + [ 18 ] = KEY_POWER, + [ 1 ] = KEY_TV, // DVR + [ 21 ] = KEY_DVD, // DVD + [ 23 ] = KEY_AUDIO, // music + // DVR mode / DVD mode / music mode + + [ 27 ] = KEY_MUTE, // mute + [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek + [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek + [ 22 ] = KEY_ZOOM, // full screen + [ 28 ] = KEY_VIDEO, // video source / eject / delall + [ 29 ] = KEY_RESTART, // playback / angle / del + [ 47 ] = KEY_SEARCH, // scan / menu / playlist + [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo + + [ 49 ] = KEY_HELP, // help + [ 50 ] = KEY_MODE, // num/memo + [ 51 ] = KEY_ESC, // cancel [ 12 ] = KEY_UP, // up [ 16 ] = KEY_DOWN, // down @@ -148,24 +150,24 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { [ 45 ] = KEY_PLAY, // play [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle - [ 0 ] = KEY_KP0, - [ 5 ] = KEY_KP1, - [ 6 ] = KEY_KP2, - [ 7 ] = KEY_KP3, - [ 9 ] = KEY_KP4, - [ 10 ] = KEY_KP5, - [ 11 ] = KEY_KP6, - [ 13 ] = KEY_KP7, - [ 14 ] = KEY_KP8, - [ 15 ] = KEY_KP9, - - [ 42 ] = KEY_VOLUMEUP, - [ 17 ] = KEY_VOLUMEDOWN, - [ 24 ] = KEY_CHANNELUP, // CH.tracking up - [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down - - [ 19 ] = KEY_KPENTER, // enter - [ 33 ] = KEY_KPDOT, // . (decimal dot) + [ 0 ] = KEY_KP0, + [ 5 ] = KEY_KP1, + [ 6 ] = KEY_KP2, + [ 7 ] = KEY_KP3, + [ 9 ] = KEY_KP4, + [ 10 ] = KEY_KP5, + [ 11 ] = KEY_KP6, + [ 13 ] = KEY_KP7, + [ 14 ] = KEY_KP8, + [ 15 ] = KEY_KP9, + + [ 42 ] = KEY_VOLUMEUP, + [ 17 ] = KEY_VOLUMEDOWN, + [ 24 ] = KEY_CHANNELUP, // CH.tracking up + [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down + + [ 19 ] = KEY_KPENTER, // enter + [ 33 ] = KEY_KPDOT, // . (decimal dot) }; static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { @@ -401,7 +403,183 @@ static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = { // 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 ? */ + +}; + +static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { + [ 0x59 ] = KEY_MUTE, + [ 0x4a ] = KEY_POWER, + + [ 0x18 ] = KEY_TEXT, + [ 0x26 ] = KEY_TV, + [ 0x3d ] = KEY_PRINT, + + [ 0x48 ] = KEY_RED, + [ 0x04 ] = KEY_GREEN, + [ 0x11 ] = KEY_YELLOW, + [ 0x00 ] = KEY_BLUE, + + [ 0x2d ] = KEY_VOLUMEUP, + [ 0x1e ] = KEY_VOLUMEDOWN, + + [ 0x49 ] = KEY_MENU, + + [ 0x16 ] = KEY_CHANNELUP, + [ 0x17 ] = KEY_CHANNELDOWN, + + [ 0x20 ] = KEY_UP, + [ 0x21 ] = KEY_DOWN, + [ 0x22 ] = KEY_LEFT, + [ 0x23 ] = KEY_RIGHT, + [ 0x0d ] = KEY_SELECT, + + + + [ 0x08 ] = KEY_BACK, + [ 0x07 ] = KEY_REFRESH, + + [ 0x2f ] = KEY_ZOOM, + [ 0x29 ] = KEY_RECORD, + + [ 0x4b ] = KEY_PAUSE, + [ 0x4d ] = KEY_REWIND, + [ 0x2e ] = KEY_PLAY, + [ 0x4e ] = KEY_FORWARD, + [ 0x53 ] = KEY_PREVIOUS, + [ 0x4c ] = KEY_STOP, + [ 0x54 ] = KEY_NEXT, + + [ 0x69 ] = KEY_KP0, + [ 0x6a ] = KEY_KP1, + [ 0x6b ] = KEY_KP2, + [ 0x6c ] = KEY_KP3, + [ 0x6d ] = KEY_KP4, + [ 0x6e ] = KEY_KP5, + [ 0x6f ] = KEY_KP6, + [ 0x70 ] = KEY_KP7, + [ 0x71 ] = KEY_KP8, + [ 0x72 ] = KEY_KP9, + + [ 0x74 ] = KEY_CHANNEL, + [ 0x0a ] = KEY_BACKSPACE, +}; + +/* 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) { @@ -413,13 +591,13 @@ static int build_key(struct saa7134_dev *dev) 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; - } + if (ir->polling) { + if (ir->last_gpio == gpio) + return 0; + ir->last_gpio = gpio; + } - data = ir_extract_bits(gpio, ir->mask_keycode); + 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); @@ -432,13 +610,87 @@ static int build_key(struct saa7134_dev *dev) 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; +} + +/* The new pinnacle PCTV remote (with the colored buttons) + * + * Ricardo Cerqueira <v4l@cerqueira.org> + */ + +static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char b[4]; + unsigned int start = 0,parity = 0,code = 0; + + /* poll IR chip */ + if (4 != i2c_master_recv(&ir->c,b,4)) { + i2cdprintk("read error\n"); + return -EIO; + } + + for (start = 0; start<4; start++) { + if (b[start] == 0x80) { + code=b[(start+3)%4]; + parity=b[(start+2)%4]; + } + } + + /* Empty Request */ + if (parity==0) + return 0; + + /* Repeating... */ + if (ir->old == parity) + return 0; + + + ir->old = parity; + + /* Reduce code value to fit inside IR_KEYTAB_SIZE + * + * this is the only value that results in 42 unique + * codes < 128 + */ + + code %= 0x88; + + *ir_raw = code; + *ir_key = code; + + i2cdprintk("Pinnacle PCTV key %02x\n", code); + + return 1; +} + void saa7134_input_irq(struct saa7134_dev *dev) { - struct saa7134_ir *ir = dev->remote; + struct saa7134_ir *ir = dev->remote; - if (!ir->polling) + if (!ir->polling) build_key(dev); } @@ -464,7 +716,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) int polling = 0; int ir_type = IR_TYPE_OTHER; - if (!dev->has_remote) + if (dev->has_remote != SAA7134_REMOTE_GPIO) return -ENODEV; if (disable_ir) return -ENODEV; @@ -473,7 +725,8 @@ int saa7134_input_init1(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_FLYVIDEO2000: case SAA7134_BOARD_FLYVIDEO3000: - case SAA7134_BOARD_FLYTVPLATINUM_FM: + case SAA7134_BOARD_FLYTVPLATINUM_FM: + case SAA7134_BOARD_FLYTVPLATINUM_MINI2: ir_codes = flyvideo_codes; mask_keycode = 0xEC00000; mask_keydown = 0x0040000; @@ -514,14 +767,33 @@ int saa7134_input_init1(struct saa7134_dev *dev) 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; - mask_keydown = 0x002000; 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; @@ -529,6 +801,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) 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", @@ -548,7 +826,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) ir->mask_keycode = mask_keycode; ir->mask_keydown = mask_keydown; ir->mask_keyup = mask_keyup; - ir->polling = polling; + ir->polling = polling; /* init input device */ snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", @@ -596,6 +874,31 @@ void saa7134_input_fini(struct saa7134_dev *dev) 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 |