Here is the patch for the remote to work. It does conflict with the KNC1 devices since it shares the same address as with the Kworld ATSC110. I'm going to fix up the patch and submit it to v4l/dvb. Hopefully before my holidays are over... It's been awhile since I have patched a copy of v4l/dvb cvs.
diff -rup /usr/src/a/linux/drivers/media/common/ir-keymaps.c /usr/src/b/linux/drivers/media/common/ir-keymaps.c
--- /usr/src/a/linux/drivers/media/common/ir-keymaps.c 2006-09-17 15:47:30.000000000 +0000
+++ /usr/src/b/linux/drivers/media/common/ir-keymaps.c 2006-09-17 14:19:46.000000000 +0000
@@ -64,6 +64,60 @@ IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_
};
EXPORT_SYMBOL_GPL(ir_codes_proteus_2309);
+
+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 */
+ [ 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);
+
/* Matt Jesson <dvb@jesson.eclipse.co.uk */
IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
[ 0x28 ] = KEY_0, //'0' / 'enter'
diff -rup /usr/src/a/linux/drivers/media/video/ir-kbd-i2c.c /usr/src/b/linux/drivers/media/video/ir-kbd-i2c.c
--- /usr/src/a/linux/drivers/media/video/ir-kbd-i2c.c 2006-09-17 15:47:30.000000000 +0000
+++ /usr/src/b/linux/drivers/media/video/ir-kbd-i2c.c 2006-09-17 13:17:36.000000000 +0000
@@ -348,10 +348,9 @@ static int ir_attach(struct i2c_adapter
}
break;
case 0x30:
- name = "KNC One";
- ir->get_key = get_key_knc1;
+ name = "Kworld ATSC110";
ir_type = IR_TYPE_OTHER;
- ir_codes = ir_codes_empty;
+ ir_codes = ir_codes_kworld_atsc110;
break;
case 0x7a:
case 0x47:
@@ -439,7 +438,7 @@ static int ir_probe(struct i2c_adapter *
*/
static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
- static const int probe_saa7134[] = { 0x7a, 0x47, -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;
@@ -468,6 +467,36 @@ static int ir_probe(struct i2c_adapter *
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 -rup /usr/src/a/linux/drivers/media/video/saa7134/saa7134-cards.c /usr/src/b/linux/drivers/media/video/saa7134/saa7134-cards.c
--- /usr/src/a/linux/drivers/media/video/saa7134/saa7134-cards.c 2006-09-17 15:47:30.000000000 +0000
+++ /usr/src/b/linux/drivers/media/video/saa7134/saa7134-cards.c 2006-09-17 12:46:37.000000000 +0000
@@ -3799,6 +3799,7 @@ int saa7134_board_init1(struct saa7134_d
break;
/* i2c remotes */
case SAA7134_BOARD_PINNACLE_PCTV_110i:
+ case SAA7134_BOARD_KWORLD_ATSC110:
case SAA7134_BOARD_UPMOST_PURPLE_TV:
dev->has_remote = SAA7134_REMOTE_I2C;
break;
diff -rup /usr/src/a/linux/drivers/media/video/saa7134/saa7134-i2c.c /usr/src/b/linux/drivers/media/video/saa7134/saa7134-i2c.c
--- /usr/src/a/linux/drivers/media/video/saa7134/saa7134-i2c.c 2006-09-17 15:47:30.000000000 +0000
+++ /usr/src/b/linux/drivers/media/video/saa7134/saa7134-i2c.c 2006-09-17 12:47:59.000000000 +0000
@@ -351,6 +351,8 @@ static int attach_inform(struct i2c_clie
switch (client->addr) {
case 0x7a:
case 0x47:
+ case 0xc2:
+ case 0x30:
{
struct IR_i2c *ir = i2c_get_clientdata(client);
d1printk("%s i2c IR detected (%s).\n",
diff -rup /usr/src/a/linux/drivers/media/video/saa7134/saa7134-input.c /usr/src/b/linux/drivers/media/video/saa7134/saa7134-input.c
--- /usr/src/a/linux/drivers/media/video/saa7134/saa7134-input.c 2006-09-17 15:47:30.000000000 +0000
+++ /usr/src/b/linux/drivers/media/video/saa7134/saa7134-input.c 2006-09-17 13:08:17.000000000 +0000
@@ -113,6 +113,49 @@ static int get_key_purpletv(struct IR_i2
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 saa7134_ir *ir = dev->remote;
@@ -181,6 +224,12 @@ int saa7134_input_init1(struct saa7134_d
break;
case SAA7134_BOARD_MD2819:
case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
+ case SAA7134_BOARD_KWORLD_ATSC110:
+ ir_codes = ir_codes_kworld_atsc110;
+ mask_keycode = 0x0;
+ mask_keydown = 0x0;
+ polling = 50; // ms
+ break;
case SAA7134_BOARD_AVERMEDIA_305:
case SAA7134_BOARD_AVERMEDIA_307:
case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
@@ -346,6 +395,11 @@ void saa7134_set_i2c_ir(struct saa7134_d
ir->get_key = get_key_purpletv;
ir->ir_codes = ir_codes_purpletv;
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 -rup /usr/src/a/linux/include/media/ir-common.h /usr/src/b/linux/include/media/ir-common.h
--- /usr/src/a/linux/include/media/ir-common.h 2006-09-17 15:47:30.000000000 +0000
+++ /usr/src/b/linux/include/media/ir-common.h 2006-09-17 12:57:33.000000000 +0000
@@ -92,6 +92,7 @@ extern IR_KEYTAB_TYPE ir_codes_hauppauge
extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_kworld_atsc110[IR_KEYTAB_SIZE];
#endif
|