From: Gerd Knorr This patch updates the ir-kbd-gpio and ir-kbd-i2c drivers. Nothing major, just some keytable fixes and support for more hardware. Signed-off-by: Andrew Morton --- 25-akpm/drivers/media/video/ir-kbd-gpio.c | 82 ++++++++++---------- 25-akpm/drivers/media/video/ir-kbd-i2c.c | 122 ++++++++++++++++++++++++++---- 2 files changed, 147 insertions(+), 57 deletions(-) diff -puN drivers/media/video/ir-kbd-gpio.c~v4l-ir-input-driver-update drivers/media/video/ir-kbd-gpio.c --- 25/drivers/media/video/ir-kbd-gpio.c~v4l-ir-input-driver-update 2004-06-19 13:58:33.626705840 -0700 +++ 25-akpm/drivers/media/video/ir-kbd-gpio.c 2004-06-19 13:58:33.633704776 -0700 @@ -1,3 +1,4 @@ + /* * Copyright (c) 2003 Gerd Knorr * Copyright (c) 2003 Pavel Machek @@ -32,47 +33,45 @@ /* ---------------------------------------------------------------------- */ static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = { - [ 17 ] = KEY_KP0, - [ 20 ] = KEY_KP1, - [ 12 ] = KEY_KP2, - [ 28 ] = KEY_KP3, - [ 18 ] = KEY_KP4, - [ 10 ] = KEY_KP5, - [ 26 ] = KEY_KP6, - [ 22 ] = KEY_KP7, - [ 14 ] = KEY_KP8, - [ 30 ] = KEY_KP9, + [ 34 ] = KEY_KP0, + [ 40 ] = KEY_KP1, + [ 24 ] = KEY_KP2, + [ 56 ] = KEY_KP3, + [ 36 ] = KEY_KP4, + [ 20 ] = KEY_KP5, + [ 52 ] = KEY_KP6, + [ 44 ] = KEY_KP7, + [ 28 ] = KEY_KP8, + [ 60 ] = KEY_KP9, - [ 24 ] = KEY_EJECTCD, // Unmarked on my controller + [ 48 ] = KEY_EJECTCD, // Unmarked on my controller [ 0 ] = KEY_POWER, - [ 9 ] = BTN_LEFT, // DISPLAY/L - [ 25 ] = BTN_RIGHT, // LOOP/R - [ 5 ] = KEY_MUTE, - [ 19 ] = KEY_RECORD, - [ 11 ] = KEY_PAUSE, - [ 27 ] = KEY_STOP, - [ 15 ] = KEY_VOLUMEDOWN, - [ 31 ] = KEY_VOLUMEUP, - - [ 16 ] = KEY_TUNER, // TV/FM - [ 8 ] = KEY_CD, - [ 4 ] = KEY_VIDEO, - [ 2 ] = KEY_AUDIO, - [ 6 ] = KEY_ZOOM, // full screen - [ 1 ] = KEY_INFO, // preview - [ 21 ] = KEY_SEARCH, // autoscan - [ 13 ] = KEY_STOP, // freeze - [ 29 ] = KEY_RECORD, // capture - [ 3 ] = KEY_PLAY, // unmarked - [ 23 ] = KEY_RED, // unmarked - [ 7 ] = KEY_GREEN, // unmarked - -#if 0 - [ 16 ] = KEY_YELLOW, // unmarked - [ 8 ] = KEY_CHANNELDOWN, - [ 24 ] = KEY_CHANNELUP, - [ 0 ] = KEY_BLUE, // unmarked -#endif + [ 18 ] = BTN_LEFT, // DISPLAY/L + [ 50 ] = BTN_RIGHT, // LOOP/R + [ 10 ] = KEY_MUTE, + [ 38 ] = KEY_RECORD, + [ 22 ] = KEY_PAUSE, + [ 54 ] = KEY_STOP, + [ 30 ] = KEY_VOLUMEDOWN, + [ 62 ] = KEY_VOLUMEUP, + + [ 32 ] = KEY_TUNER, // TV/FM + [ 16 ] = KEY_CD, + [ 8 ] = KEY_VIDEO, + [ 4 ] = KEY_AUDIO, + [ 12 ] = KEY_ZOOM, // full screen + [ 2 ] = KEY_INFO, // preview + [ 42 ] = KEY_SEARCH, // autoscan + [ 26 ] = KEY_STOP, // freeze + [ 58 ] = KEY_RECORD, // capture + [ 6 ] = KEY_PLAY, // unmarked + [ 46 ] = KEY_RED, // unmarked + [ 14 ] = KEY_GREEN, // unmarked + + [ 33 ] = KEY_YELLOW, // unmarked + [ 17 ] = KEY_CHANNELDOWN, + [ 49 ] = KEY_CHANNELUP, + [ 1 ] = KEY_BLUE, // unmarked }; static IR_KEYTAB_TYPE winfast_codes[IR_KEYTAB_SIZE] = { @@ -280,8 +279,9 @@ static int ir_probe(struct device *dev) case BTTV_AVPHONE98: case BTTV_AVERMEDIA98: ir_codes = ir_codes_avermedia; - ir->mask_keycode = 0xf80000; + ir->mask_keycode = 0xf88000; ir->mask_keydown = 0x010000; + ir->polling = 50; // ms break; case BTTV_PXELVWPLTVPAK: @@ -300,7 +300,7 @@ static int ir_probe(struct device *dev) case BTTV_WINFAST2000: ir_codes = winfast_codes; - ir->mask_keycode = 0x8f8; + ir->mask_keycode = 0x1f8; break; case BTTV_MAGICTVIEW061: case BTTV_MAGICTVIEW063: diff -puN drivers/media/video/ir-kbd-i2c.c~v4l-ir-input-driver-update drivers/media/video/ir-kbd-i2c.c --- 25/drivers/media/video/ir-kbd-i2c.c~v4l-ir-input-driver-update 2004-06-19 13:58:33.628705536 -0700 +++ 25-akpm/drivers/media/video/ir-kbd-i2c.c 2004-06-19 13:58:33.634704624 -0700 @@ -77,6 +77,56 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_ [ 15 ] = KEY_SELECT, // SOURCE [ 10 ] = KEY_KPPLUS, // +100 [ 20 ] = KEY_KPEQUAL, // SYNC + [ 28 ] = KEY_MEDIA, // PC/TV +}; + +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 +#if 0 + [ 0x1f ] = KEY_S, // Snapshot +#endif + [ 0x49 ] = KEY_LANGUAGE, // MTS Select + [ 0x19 ] = KEY_SEARCH, // Auto Scan + + [ 0x4b ] = KEY_RECORD, + [ 0x46 ] = KEY_PLAY, + [ 0x45 ] = KEY_PAUSE, // Pause + [ 0x44 ] = KEY_STOP, +#if 0 + [ 0x43 ] = KEY_T, // Time Shift + [ 0x47 ] = KEY_Y, // Time Shift OFF + [ 0x4a ] = KEY_O, // TOP + [ 0x17 ] = KEY_F, // SURF CH +#endif + [ 0x40 ] = KEY_FORWARD, // Forward ? + [ 0x42 ] = KEY_REWIND, // Backward ? + }; struct IR; @@ -202,11 +252,33 @@ static int get_key_knc1(struct IR *ir, u return 1; } +static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char b; + + /* poll IR chip */ + if (1 != i2c_master_recv(&ir->c,&b,1)) { + dprintk(1,"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; +} /* ----------------------------------------------------------------------- */ static void ir_key_poll(struct IR *ir) { - u32 ir_key, ir_raw; + static u32 ir_key, ir_raw; int rc; dprintk(2,"ir_poll_key\n"); @@ -300,6 +372,12 @@ static int ir_attach(struct i2c_adapter ir_type = IR_TYPE_OTHER; ir_codes = ir_codes_empty; break; + case 0x7a: + name = "Purple TV"; + ir->get_key = get_key_purpletv; + ir_type = IR_TYPE_OTHER; + ir_codes = ir_codes_purpletv; + break; default: /* shouldn't happen */ printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr); @@ -320,7 +398,8 @@ static int ir_attach(struct i2c_adapter ir->input.name = ir->c.name; ir->input.phys = ir->phys; input_register_device(&ir->input); - printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys); + printk(DEVNAME ": %s detected at %s [%s]\n", + ir->input.name,ir->input.phys,adap->name); /* start polling via eventd */ INIT_WORK(&ir->work, ir_work, ir); @@ -361,22 +440,33 @@ static int ir_probe(struct i2c_adapter * That's why we probe 0x1a (~0x34) first. CB */ - static const int probe[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; + static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; + static const int probe_saa7134[] = { 0x7a, -1}; + const int *probe = NULL; struct i2c_client c; char buf; int i,rc; - if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) { - memset(&c,0,sizeof(c)); - c.adapter = adap; - for (i = 0; -1 != probe[i]; i++) { - c.addr = probe[i]; - rc = i2c_master_recv(&c,&buf,1); - dprintk(1,"probe 0x%02x @ %s: %s\n", - probe[i], adap->name, - (1 == rc) ? "yes" : "no"); - if (1 == rc) { - ir_attach(adap,probe[i],0,0); - break; - } + switch (adap->id) { + case I2C_ALGO_BIT | I2C_HW_B_BT848: + probe = probe_bttv; + break; + case I2C_ALGO_SAA7134: + probe = probe_saa7134; + break; + } + if (NULL == probe) + return 0; + + memset(&c,0,sizeof(c)); + c.adapter = adap; + for (i = 0; -1 != probe[i]; i++) { + c.addr = probe[i]; + rc = i2c_master_recv(&c,&buf,1); + dprintk(1,"probe 0x%02x @ %s: %s\n", + probe[i], adap->name, + (1 == rc) ? "yes" : "no"); + if (1 == rc) { + ir_attach(adap,probe[i],0,0); + break; } } return 0; _