Been testing this patch for a couple of weeks. Functionality works great. A lot of people have been requesting
this patch.
Patch contents:
- Add ir remote functionality for the Kworld ATSC110 HDTV tuner card.
Signed-off-by: Dwaine P. Garden <DwaineGarden@xxxxxxxxxx>
this patch.
Patch contents:
- Add ir remote functionality for the Kworld ATSC110 HDTV tuner card.
Signed-off-by: Dwaine P. Garden <DwaineGarden@xxxxxxxxxx>
diff -U 3 -H -d -r -N -- a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c --- a/linux/drivers/media/common/ir-keymaps.c 2007-01-01 03:10:56.000000000 -0500 +++ b/linux/drivers/media/common/ir-keymaps.c 2007-01-01 05:59:58.000000000 -0500 @@ -1789,3 +1789,58 @@ }; EXPORT_SYMBOL_GPL(ir_codes_encore_enltv); + +IR_KEYTAB_TYPE ir_codes_kworld_atsc110[IR_KEYTAB_SIZE] = { + [ 0x0 ] = KEY_1, + [ 0x1 ] = KEY_2, + [ 0x2 ] = KEY_3, + [ 0x3 ] = KEY_4, + [ 0x4 ] = KEY_5, + [ 0x5 ] = KEY_6, + [ 0x6 ] = KEY_7, + [ 0x7 ] = KEY_8, + [ 0x8 ] = KEY_9, + [ 0xa ] = KEY_0, + [ 0x9 ] = KEY_ESC, /* UP ARROW */ + [ 0xc ] = KEY_POWER, /* POWER */ + [ 0x0a ] = KEY_MUTE, /* MUTE */ + [ 0x0b ] = KEY_SEARCH, /* SEARCH */ + [ 0x0d ] = KEY_EPG, /* GUIDE */ + [ 0x1b ] = KEY_RECORD, /* RECORD */ + [ 0x16 ] = KEY_PAUSE, /* PAUSE */ + [ 0x1a ] = KEY_STOP, /* STOP */ + [ 0x1d ] = KEY_VOLUMEDOWN, /* VOLUME- */ + [ 0x1c ] = KEY_VOLUMEUP, /* VOLUME+ */ + [ 0x1f ] = KEY_CHANNELDOWN, /* CHANNEL/PAGE- */ + [ 0x1e ] = KEY_CHANNELUP, /* CHANNEL/PAGE+ */ + [ 0x10 ] = KEY_UP, /* KEY_SCROLLUP */ + [ 0x12 ] = KEY_LEFT, /* KEY_BACK */ + [ 0xe ] = KEY_ENTER, /* KEY_ENTER */ + [ 0x13 ] = KEY_RIGHT, /* KEY_FORWARD */ + [ 0x11 ] = KEY_DOWN, /* KEY_SCROLLDOWN */ + [ 0x14 ] = KEY_MUTE, /* MUTE */ + [ 0x15 ] = KEY_AUDIO, /* STEREO */ + [ 0x16 ] = KEY_VIDEO, /* SOURCE */ + [ 0x17 ] = KEY_ZOOM, /* ZOOM */ + [ 0x18 ] = KEY_PRINT, /* SHUTDOWN */ + [ 0X19 ] = KEY_T, /* TIMESHIFT */ + [ 0x44 ] = KEY_PLAYPAUSE, /* PAUSE/PLAY */ + [ 0x45 ] = KEY_STOP, /* STOP */ + [ 0x40 ] = KEY_REWIND, /* REWIND */ + [ 0x41 ] = KEY_FORWARD, /* FASTFORWARD */ + [ 0x42 ] = KEY_PREVIOUSSONG, /* PREVIOUS */ + [ 0x43 ] = KEY_NEXTSONG, /* NEXT */ + + /* buttons a-h */ + [ 0x48 ] = KEY_A, + [ 0x49 ] = KEY_B, + [ 0x4a ] = KEY_C, + [ 0x4b ] = KEY_D, + [ 0x4c ] = KEY_E, + [ 0x4d ] = KEY_F, + [ 0x4e ] = KEY_G, + [ 0x4f ] = KEY_H +}; + +EXPORT_SYMBOL_GPL(ir_codes_kworld_atsc110); + diff -U 3 -H -d -r -N -- a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c --- a/linux/drivers/media/video/ir-kbd-i2c.c 2007-01-01 03:10:56.000000000 -0500 +++ b/linux/drivers/media/video/ir-kbd-i2c.c 2007-01-01 03:45:41.000000000 -0500 @@ -55,6 +55,11 @@ module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */ MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)"); +static int kworldatsc110 = 0; +module_param(kworldatsc110, int, 0644); /* Choose a Kworld ATSC110 remote */ +MODULE_PARM_DESC(hauppauge, "Specify a Kworld HDTV ATSC110 remote: 0=No, 1=Yes (defaults to 0)"); + + #define DEVNAME "ir-kbd-i2c" #define dprintk(level, fmt, arg...) if (debug >= level) \ @@ -207,6 +212,30 @@ return 1; } +static int get_key_kworld_atsc110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char b; + + if (1 != i2c_master_recv(&ir->c,&b,1)) { + dprintk(1,"read error\n"); + return -EIO; + } + + dprintk(2,"key %02x\n", b); + + /* No button press */ + if (b == 0xFF) + return 0; + + /* repeating */ + if (b & 0x80) + return 1; + + *ir_key = b; + *ir_raw = b; + return 1; +} + /* The grey pinnacle PCTV remote * * There are one issue with this remote: @@ -364,10 +393,17 @@ } break; case 0x30: - name = "KNC One"; - ir->get_key = get_key_knc1; - ir_type = IR_TYPE_OTHER; - ir_codes = ir_codes_empty; + if (kworldatsc110 == 1) { + name = "Kworld ATSC110"; + ir->get_key = get_key_kworld_atsc110; + ir_type = IR_TYPE_OTHER; + ir_codes = ir_codes_kworld_atsc110; + } else { + name = "KNC One"; + ir->get_key = get_key_knc1; + ir_type = IR_TYPE_OTHER; + ir_codes = ir_codes_empty; + } break; case 0x7a: case 0x47: @@ -470,7 +506,7 @@ */ static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; - static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 }; + static const int probe_saa7134[] = { 0x7a, 0x47, 0x30, -1 }; static const int probe_em28XX[] = { 0x30, 0x47, -1 }; const int *probe = NULL; struct i2c_client c; @@ -499,6 +535,36 @@ for (i = 0; -1 != probe[i]; i++) { c.addr = probe[i]; rc = i2c_master_recv(&c,&buf,0); + + /* Special case for Kworld ATSC110 remote */ + if (c.adapter->id == I2C_HW_SAA7134 && probe[i] == 0x30) + { + struct i2c_client c2; + + dprintk(1,"Attempting special probe at 0x%x\n", probe[i]); + + memset (&c2, 0, sizeof(c2)); + c2.adapter = c.adapter; + + /* Find a device that responds. If none found, oh well. */ + for (c2.addr=127; c2.addr > 0; c2.addr--) + { + if (0 == i2c_master_recv(&c2,&buf,0)) { + dprintk(1,"found another device, at addr 0x%02x\n", c2.addr); + break; + } + } + + /* Now do the probe. The controller does not respond + to 0-byte reads, so we use a 1-byte read instead. */ + rc = i2c_master_recv(&c,&buf,1); + rc--; + } + else + { + rc = i2c_master_recv(&c,&buf,0); + } + dprintk(1,"probe 0x%02x @ %s: %s\n", probe[i], adap->name, (0 == rc) ? "yes" : "no"); diff -U 3 -H -d -r -N -- a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c --- a/linux/drivers/media/video/saa7134/saa7134-cards.c 2007-01-01 03:10:56.000000000 -0500 +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c 2007-01-01 04:09:05.000000000 -0500 @@ -4173,6 +4173,7 @@ dev->has_remote = SAA7134_REMOTE_I2C; break; case SAA7134_BOARD_AVERMEDIA_A169_B: + case SAA7134_BOARD_KWORLD_ATSC110: case SAA7134_BOARD_MD7134_BRIDGE_2: printk("%s: %s: dual saa713x broadcast decoders\n" "%s: Sorry, none of the inputs to this chip are supported yet.\n" diff -U 3 -H -d -r -N -- a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c --- a/linux/drivers/media/video/saa7134/saa7134-i2c.c 2007-01-01 03:10:56.000000000 -0500 +++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c 2007-01-01 03:35:04.000000000 -0500 @@ -352,6 +352,8 @@ case 0x7a: case 0x47: case 0x71: + case 0xc2: + case 0x30: { struct IR_i2c *ir = i2c_get_clientdata(client); d1printk("%s i2c IR detected (%s).\n", diff -U 3 -H -d -r -N -- a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c --- a/linux/drivers/media/video/saa7134/saa7134-input.c 2007-01-01 03:10:56.000000000 -0500 +++ b/linux/drivers/media/video/saa7134/saa7134-input.c 2007-01-01 03:40:47.000000000 -0500 @@ -142,6 +142,49 @@ return 1; } +static int get_key_kworld_atsc110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char b; + int rc; + int gpio; + + + /* We need this to access GPIO. Used by the saa_readl macro. */ + struct saa7134_dev *dev = ir->c.adapter->algo_data; + if (dev == NULL) { + dprintk ("ir->c.adapter->algo_data is NULL!\n"); + return -EIO; + } + + /* 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 (gpio & 0x100) + return 0; /* No button press */ + + + /* GPIO says there is a button press. Get it. */ + if (1 != (rc=i2c_master_recv(&ir->c,&b,1))) { + dprintk("read error %d\n", rc); + return -EIO; + } + + /* No button press */ + if (b == 0xFF) + 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 card_ir *ir = dev->remote; @@ -334,6 +377,12 @@ mask_keyup = 0x040000; polling = 50; // ms break; + case SAA7134_BOARD_KWORLD_ATSC110: + ir_codes = ir_codes_kworld_atsc110; + mask_keycode = 0x0; + mask_keydown = 0x0; + polling = 50; // ms + break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", @@ -442,6 +491,11 @@ ir->get_key = get_key_hvr1110; ir->ir_codes = ir_codes_hauppauge_new; break; + case SAA7134_BOARD_KWORLD_ATSC110: + snprintf(ir->c.name, sizeof(ir->c.name), "Kworld ATSC110"); + ir->get_key = get_key_kworld_atsc110; + ir->ir_codes = ir_codes_kworld_atsc110; + break; default: dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); break; diff -U 3 -H -d -r -N -- a/linux/include/media/ir-common.h b/linux/include/media/ir-common.h --- a/linux/include/media/ir-common.h 2007-01-01 03:10:56.000000000 -0500 +++ b/linux/include/media/ir-common.h 2007-01-01 03:41:36.000000000 -0500 @@ -139,7 +139,7 @@ extern IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE]; - +extern IR_KEYTAB_TYPE ir_codes_kworld_atsc110[IR_KEYTAB_SIZE]; #endif /*
_______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb