|
|
|
Re: Asus P7131 Remote Control (includes patch) | |
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] | |
Hi there, It's been somedays out... but here it is, almost fully working and I tried to get the bt8xx and saa7134 rc5 toghether. In brief, what I did: * Moved the rc5_decode and rc5_timer_end from bt8xx to ir-functions.c to share it among others. * moved structs bttv_ir and saa7134_ir to a unique card_ir under ir-common.h (rc5_timer_end expects it) * Tried to get it working again... The only thing I'm sure isn't working are all the dprintk()'s in the new functions in ir-functions.c so I changed them to printk()'s for testing, but that makes a lot of noise on dmesg so if somebody know how to put back the dprintk's... ;) And! I have no bt8xx to make sure I didn't break something, so If anybody with a bt8xx can try his rc5 remote I'd be glad. For the rest I thing I didn't do anything bad... hope so! And if somebody is bored.. (saa7134|bttv)_rc5_irq is still waitting for somebody trying to get it into one... hehe. There's another driver which uses the *_ir struct but seems harder to move. The patch is agains current HG. If needed. Signed-off-by: Marc Fargas <telenieko@xxxxxxxxxxxxx> (don't know how to add the signed-off-by to a patch, hehe). Cheers, Marc Fargas On 9/3/06, hermann pitton <hermann-pitton@xxxxxxxx> wrote:
Hi Marc, the same keys is fine! With the toggle bit back in the recent version of the patch it is all OK. Yes, key timing is really quick, didn't change it yet. What about it when loading saa7134 with "rc5_key_timeout=50" ? Thanks for all! Cheers, Hermann
-- The probability of failure of a (computer) system is exponentially proportional to the physical distance between it and the one who could fix it. -- Martin F. Krafft
diff -r 12f0f1ce18b1 linux/drivers/media/common/ir-functions.c
--- a/linux/drivers/media/common/ir-functions.c Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/drivers/media/common/ir-functions.c Thu Sep 28 22:28:14 2006 +0200
@@ -263,6 +263,114 @@ int ir_decode_biphase(u32 *samples, int
return value;
}
+/* RC5 decoding stuff, moved from bttv-input.c to share it with
+ * saa7134 */
+
+
+/* decode raw bit pattern to RC5 code */
+u32 ir_rc5_decode(unsigned int code)
+{
+ unsigned int org_code = code;
+ unsigned int pair;
+ unsigned int rc5 = 0;
+ int i;
+
+ for (i = 0; i < 14; ++i) {
+ pair = code & 0x3;
+ code >>= 2;
+
+ rc5 <<= 1;
+ switch (pair) {
+ case 0:
+ case 2:
+ break;
+ case 1:
+ rc5 |= 1;
+ break;
+ case 3:
+ printk("ir-common: ir_rc5_decode(%x) bad code\n", org_code);
+ return 0;
+ }
+ }
+ printk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
+ "instr=%x\n", rc5, org_code, RC5_START(rc5),
+ RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
+ return rc5;
+}
+
+
+void ir_rc5_timer_end(unsigned long data)
+{
+ struct card_ir *ir = (struct card_ir *)data;
+ struct timeval tv;
+ unsigned long current_jiffies, timeout;
+ u32 gap;
+ u32 rc5 = 0;
+
+ /* get time */
+ current_jiffies = jiffies;
+ do_gettimeofday(&tv);
+
+ /* avoid overflow with gap >1s */
+ if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+ gap = 200000;
+ } else {
+ gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+ tv.tv_usec - ir->base_time.tv_usec;
+ }
+
+ /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
+ if (gap < 28000) {
+ printk("spurious timer_end\n");
+ return;
+ }
+
+ ir->active = 0;
+ if (ir->last_bit < 20) {
+ /* ignore spurious codes (caused by light/other remotes) */
+ printk("short code: %x\n", ir->code);
+ } else {
+ ir->code = (ir->code << ir->shift_by) | 1;
+ rc5 = ir_rc5_decode(ir->code);
+
+ /* two start bits? */
+ if (RC5_START(rc5) != ir->start) {
+ printk("rc5 start bits invalid: %u\n", RC5_START(rc5));
+
+ /* right address? */
+ } else if (RC5_ADDR(rc5) == ir->addr) {
+ u32 toggle = RC5_TOGGLE(rc5);
+ u32 instr = RC5_INSTR(rc5);
+
+ /* Good code, decide if repeat/repress */
+ if (toggle != RC5_TOGGLE(ir->last_rc5) ||
+ instr != RC5_INSTR(ir->last_rc5)) {
+ printk("instruction %x, toggle %x\n", instr,
+ toggle);
+ ir_input_nokey(ir->dev, &ir->ir);
+ ir_input_keydown(ir->dev, &ir->ir, instr,
+ instr);
+ }
+
+ /* Set/reset key-up timer */
+ timeout = current_jiffies + (500 + ir->rc5_key_timeout
+ * HZ) / 1000;
+ mod_timer(&ir->timer_keyup, timeout);
+
+ /* Save code for repeat test */
+ ir->last_rc5 = rc5;
+ }
+ }
+}
+
+void ir_rc5_timer_keyup(unsigned long data)
+{
+ struct card_ir *ir = (struct card_ir *)data;
+
+ printk("key released\n");
+ ir_input_nokey(ir->dev, &ir->ir);
+}
+
EXPORT_SYMBOL_GPL(ir_input_init);
EXPORT_SYMBOL_GPL(ir_input_nokey);
EXPORT_SYMBOL_GPL(ir_input_keydown);
@@ -271,6 +379,10 @@ EXPORT_SYMBOL_GPL(ir_dump_samples);
EXPORT_SYMBOL_GPL(ir_dump_samples);
EXPORT_SYMBOL_GPL(ir_decode_biphase);
EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
+
+EXPORT_SYMBOL_GPL(ir_rc5_decode);
+EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
+EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
/*
* Local variables:
diff -r 12f0f1ce18b1 linux/drivers/media/common/ir-keymaps.c
--- a/linux/drivers/media/common/ir-keymaps.c Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/drivers/media/common/ir-keymaps.c Thu Sep 28 22:28:14 2006 +0200
@@ -1595,3 +1595,57 @@ IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTA
};
EXPORT_SYMBOL_GPL(ir_codes_norwood);
+
+/*
+ * Marc Fargas <telenieko@xxxxxxxxxxxxx>
+ * this is the remote control that comes with the asus p7131
+ * which has a label saying is "Model PC-39"
+ */
+IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE] = {
+ /* Keys 0 to 9 */
+ [ 0x15 ] = KEY_0,
+ [ 0x29 ] = KEY_1,
+ [ 0x2d ] = KEY_2,
+ [ 0x2b ] = KEY_3,
+ [ 0x09 ] = KEY_4,
+ [ 0x0d ] = KEY_5,
+ [ 0x0b ] = KEY_6,
+ [ 0x31 ] = KEY_7,
+ [ 0x35 ] = KEY_8,
+ [ 0x33 ] = KEY_9,
+
+ [ 0x3e ] = KEY_RADIO, /* radio */
+ [ 0x03 ] = KEY_MENU, /* dvd/menu */
+ [ 0x2a ] = KEY_VOLUMEUP,
+ [ 0x19 ] = KEY_VOLUMEDOWN,
+ [ 0x37 ] = KEY_UP,
+ [ 0x3b ] = KEY_DOWN,
+ [ 0x27 ] = KEY_LEFT,
+ [ 0x2f ] = KEY_RIGHT,
+ [ 0x25 ] = KEY_VIDEO, /* video */
+ [ 0x39 ] = KEY_AUDIO, /* music */
+
+ [ 0x21 ] = KEY_TV, /* tv */
+ [ 0x1d ] = KEY_EXIT, /* back */
+ [ 0x0a ] = KEY_CHANNELUP, /* channel / program + */
+ [ 0x1b ] = KEY_CHANNELDOWN, /* channel / program - */
+ [ 0x1a ] = KEY_ENTER, /* enter */
+
+ [ 0x06 ] = KEY_PAUSE, /* play/pause */
+ [ 0x1e ] = KEY_PREVIOUS, /* rew */
+ [ 0x26 ] = KEY_NEXT, /* forward */
+ [ 0x0e ] = KEY_REWIND, /* backward << */
+ [ 0x3a ] = KEY_FASTFORWARD, /* forward >> */
+ [ 0x36 ] = KEY_STOP,
+ [ 0x2e ] = KEY_RECORD, /* recording */
+ [ 0x16 ] = KEY_POWER, /* the button that reads "close" */
+
+ [ 0x11 ] = KEY_ZOOM, /* full screen */
+ [ 0x13 ] = KEY_MACRO, /* recall */
+ [ 0x23 ] = KEY_HOME, /* home */
+ [ 0x05 ] = KEY_PVR, /* picture */
+ [ 0x3d ] = KEY_MUTE, /* mute */
+ [ 0x01 ] = KEY_DVD, /* dvd */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_asus_pc39);
diff -r 12f0f1ce18b1 linux/drivers/media/video/bt8xx/bttv-input.c
--- a/linux/drivers/media/video/bt8xx/bttv-input.c Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/drivers/media/video/bt8xx/bttv-input.c Thu Sep 28 22:28:14 2006 +0200
@@ -37,13 +37,18 @@ static int repeat_period = 33;
static int repeat_period = 33;
module_param(repeat_period, int, 0644);
+int ir_rc5_remote_gap = 885;
+module_param(ir_rc5_remote_gap, int, 0644);
+int ir_rc5_key_timeout = 200;
+module_param(ir_rc5_key_timeout, int, 0644);
+
#define DEVNAME "bttv-input"
/* ---------------------------------------------------------------------- */
static void ir_handle_key(struct bttv *btv)
{
- struct bttv_ir *ir = btv->remote;
+ struct card_ir *ir = btv->remote;
u32 gpio,data;
/* read gpio value */
@@ -73,7 +78,7 @@ static void ir_handle_key(struct bttv *b
void bttv_input_irq(struct bttv *btv)
{
- struct bttv_ir *ir = btv->remote;
+ struct card_ir *ir = btv->remote;
if (!ir->polling)
ir_handle_key(btv);
@@ -82,7 +87,7 @@ static void bttv_input_timer(unsigned lo
static void bttv_input_timer(unsigned long data)
{
struct bttv *btv = (struct bttv*)data;
- struct bttv_ir *ir = btv->remote;
+ struct card_ir *ir = btv->remote;
unsigned long timeout;
ir_handle_key(btv);
@@ -92,51 +97,9 @@ static void bttv_input_timer(unsigned lo
/* ---------------------------------------------------------------*/
-static int rc5_remote_gap = 885;
-module_param(rc5_remote_gap, int, 0644);
-static int rc5_key_timeout = 200;
-module_param(rc5_key_timeout, int, 0644);
-
-#define RC5_START(x) (((x)>>12)&3)
-#define RC5_TOGGLE(x) (((x)>>11)&1)
-#define RC5_ADDR(x) (((x)>>6)&31)
-#define RC5_INSTR(x) ((x)&63)
-
-/* decode raw bit pattern to RC5 code */
-static u32 rc5_decode(unsigned int code)
-{
- unsigned int org_code = code;
- unsigned int pair;
- unsigned int rc5 = 0;
- int i;
-
- code = (code << 1) | 1;
- for (i = 0; i < 14; ++i) {
- pair = code & 0x3;
- code >>= 2;
-
- rc5 <<= 1;
- switch (pair) {
- case 0:
- case 2:
- break;
- case 1:
- rc5 |= 1;
- break;
- case 3:
- dprintk(KERN_WARNING "bad code: %x\n", org_code);
- return 0;
- }
- }
- dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
- "instr=%x\n", rc5, org_code, RC5_START(rc5),
- RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
- return rc5;
-}
-
static int bttv_rc5_irq(struct bttv *btv)
{
- struct bttv_ir *ir = btv->remote;
+ struct card_ir *ir = btv->remote;
struct timeval tv;
u32 gpio;
u32 gap;
@@ -166,8 +129,8 @@ static int bttv_rc5_irq(struct bttv *btv
/* only if in the code (otherwise spurious IRQ or timer
late) */
if (ir->last_bit < 28) {
- ir->last_bit = (gap - rc5_remote_gap / 2) /
- rc5_remote_gap;
+ ir->last_bit = (gap - ir_rc5_remote_gap / 2) /
+ ir_rc5_remote_gap;
ir->code |= 1 << ir->last_bit;
}
/* starting new code */
@@ -187,82 +150,11 @@ static int bttv_rc5_irq(struct bttv *btv
return 1;
}
-
-static void bttv_rc5_timer_end(unsigned long data)
-{
- struct bttv_ir *ir = (struct bttv_ir *)data;
- struct timeval tv;
- unsigned long current_jiffies, timeout;
- u32 gap;
-
- /* get time */
- current_jiffies = jiffies;
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
- if (gap < 28000) {
- dprintk(KERN_WARNING "spurious timer_end\n");
- return;
- }
-
- ir->active = 0;
- if (ir->last_bit < 20) {
- /* ignore spurious codes (caused by light/other remotes) */
- dprintk(KERN_WARNING "short code: %x\n", ir->code);
- } else {
- u32 rc5 = rc5_decode(ir->code);
-
- /* two start bits? */
- if (RC5_START(rc5) != 3) {
- dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5));
-
- /* right address? */
- } else if (RC5_ADDR(rc5) == 0x0) {
- u32 toggle = RC5_TOGGLE(rc5);
- u32 instr = RC5_INSTR(rc5);
-
- /* Good code, decide if repeat/repress */
- if (toggle != RC5_TOGGLE(ir->last_rc5) ||
- instr != RC5_INSTR(ir->last_rc5)) {
- dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr,
- toggle);
- ir_input_nokey(ir->dev, &ir->ir);
- ir_input_keydown(ir->dev, &ir->ir, instr,
- instr);
- }
-
- /* Set/reset key-up timer */
- timeout = current_jiffies + (500 + rc5_key_timeout
- * HZ) / 1000;
- mod_timer(&ir->timer_keyup, timeout);
-
- /* Save code for repeat test */
- ir->last_rc5 = rc5;
- }
- }
-}
-
-static void bttv_rc5_timer_keyup(unsigned long data)
-{
- struct bttv_ir *ir = (struct bttv_ir *)data;
-
- dprintk(KERN_DEBUG "key released\n");
- ir_input_nokey(ir->dev, &ir->ir);
-}
-
/* ---------------------------------------------------------------------- */
int bttv_input_init(struct bttv *btv)
{
- struct bttv_ir *ir;
+ struct card_ir *ir;
IR_KEYTAB_TYPE *ir_codes = NULL;
struct input_dev *input_dev;
int ir_type = IR_TYPE_OTHER;
@@ -405,12 +297,17 @@ int bttv_input_init(struct bttv *btv)
} else if (ir->rc5_gpio) {
/* set timer_end for code completion */
init_timer(&ir->timer_end);
- ir->timer_end.function = bttv_rc5_timer_end;
+ ir->timer_end.function = ir_rc5_timer_end;
ir->timer_end.data = (unsigned long)ir;
init_timer(&ir->timer_keyup);
- ir->timer_keyup.function = bttv_rc5_timer_keyup;
+ ir->timer_keyup.function = ir_rc5_timer_keyup;
ir->timer_keyup.data = (unsigned long)ir;
+ ir->shift_by = 1;
+ ir->start = 3;
+ ir->addr = 0x0;
+ ir->rc5_key_timeout = ir_rc5_key_timeout;
+ ir->rc5_remote_gap = ir_rc5_remote_gap;
}
/* all done */
diff -r 12f0f1ce18b1 linux/drivers/media/video/bt8xx/bttv.h
--- a/linux/drivers/media/video/bt8xx/bttv.h Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/drivers/media/video/bt8xx/bttv.h Thu Sep 28 22:28:14 2006 +0200
@@ -198,33 +198,6 @@ struct bttv;
struct bttv;
-struct bttv_ir {
- struct input_dev *dev;
- struct ir_input_state ir;
- char name[32];
- char phys[32];
-
- /* Usual gpio signalling */
-
- u32 mask_keycode;
- u32 mask_keydown;
- u32 mask_keyup;
- u32 polling;
- u32 last_gpio;
- struct work_struct work;
- struct timer_list timer;
-
- /* RC5 gpio */
- u32 rc5_gpio;
- struct timer_list timer_end; /* timer_end for code completion */
- struct timer_list timer_keyup; /* timer_end for key release */
- u32 last_rc5; /* last good rc5 code */
- u32 last_bit; /* last raw bit seen */
- u32 code; /* raw code under construction */
- struct timeval base_time; /* time of last seen code */
- int active; /* building raw code */
-};
-
struct tvcard
{
char *name;
diff -r 12f0f1ce18b1 linux/drivers/media/video/bt8xx/bttvp.h
--- a/linux/drivers/media/video/bt8xx/bttvp.h Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/drivers/media/video/bt8xx/bttvp.h Thu Sep 28 22:28:14 2006 +0200
@@ -322,7 +322,7 @@ struct bttv {
/* infrared remote */
int has_remote;
- struct bttv_ir *remote;
+ struct card_ir *remote;
/* locking */
spinlock_t s_lock;
diff -r 12f0f1ce18b1 linux/drivers/media/video/saa7134/saa7134-cards.c
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c Thu Sep 28 22:28:14 2006 +0200
@@ -3775,6 +3775,7 @@ int saa7134_board_init1(struct saa7134_d
case SAA7134_BOARD_KWORLD_TERMINATOR:
case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
case SAA7134_BOARD_FLYDVBT_LR301:
+ case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
case SAA7134_BOARD_FLYDVBTDUO:
case SAA7134_BOARD_PROTEUS_2309:
dev->has_remote = SAA7134_REMOTE_GPIO;
diff -r 12f0f1ce18b1 linux/drivers/media/video/saa7134/saa7134-input.c
--- a/linux/drivers/media/video/saa7134/saa7134-input.c Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/drivers/media/video/saa7134/saa7134-input.c Thu Sep 28 22:28:14 2006 +0200
@@ -42,16 +42,24 @@ module_param(pinnacle_remote, int, 0644)
module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */
MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)");
+int ir_rc5_remote_gap = 885;
+module_param(ir_rc5_remote_gap, int, 0644);
+int ir_rc5_key_timeout = 50;
+module_param(ir_rc5_key_timeout, int, 0644);
+
#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)
+/** rc5 functions */
+static int saa7134_rc5_irq(struct saa7134_dev *btv);
+
/* -------------------- GPIO generic keycode builder -------------------- */
static int build_key(struct saa7134_dev *dev)
{
- struct saa7134_ir *ir = dev->remote;
+ struct card_ir *ir = dev->remote;
u32 gpio, data;
/* rising SAA7134_GPIO_GPRESCAN reads the status */
@@ -115,16 +123,19 @@ static int get_key_purpletv(struct IR_i2
void saa7134_input_irq(struct saa7134_dev *dev)
{
- struct saa7134_ir *ir = dev->remote;
-
- if (!ir->polling)
+ struct card_ir *ir = dev->remote;
+
+ if (!ir->polling && !ir->rc5_gpio) {
build_key(dev);
+ } else if (ir->rc5_gpio) {
+ saa7134_rc5_irq(dev);
+ }
}
static void saa7134_input_timer(unsigned long data)
{
struct saa7134_dev *dev = (struct saa7134_dev*)data;
- struct saa7134_ir *ir = dev->remote;
+ struct card_ir *ir = dev->remote;
unsigned long timeout;
build_key(dev);
@@ -134,13 +145,14 @@ static void saa7134_input_timer(unsigned
int saa7134_input_init1(struct saa7134_dev *dev)
{
- struct saa7134_ir *ir;
+ struct card_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 rc5_gpio = 0;
int ir_type = IR_TYPE_OTHER;
if (dev->has_remote != SAA7134_REMOTE_GPIO)
@@ -248,6 +260,11 @@ int saa7134_input_init1(struct saa7134_d
mask_keycode = 0x0001F00;
mask_keydown = 0x0040000;
break;
+ case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
+ ir_codes = ir_codes_asus_pc39;
+ mask_keydown = 0x0040000;
+ rc5_gpio = 1;
+ break;
}
if (NULL == ir_codes) {
printk("%s: Oops: IR config error [card=%d]\n",
@@ -270,6 +287,7 @@ int saa7134_input_init1(struct saa7134_d
ir->mask_keydown = mask_keydown;
ir->mask_keyup = mask_keyup;
ir->polling = polling;
+ ir->rc5_gpio = rc5_gpio;
/* init input device */
snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
@@ -297,16 +315,31 @@ int saa7134_input_init1(struct saa7134_d
#endif
#endif
- /* 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);
- }
-
+ } else if (ir->rc5_gpio) {
+ /* set timer_end for code completion */
+ init_timer(&ir->timer_end);
+ ir->timer_end.function = ir_rc5_timer_end;
+ ir->timer_end.data = (unsigned long)ir;
+ init_timer(&ir->timer_keyup);
+ ir->timer_keyup.function = ir_rc5_timer_keyup;
+ ir->timer_keyup.data = (unsigned long)ir;
+ ir->shift_by = 2;
+ ir->start = 0x2;
+ ir->addr = 0x17;
+ ir->rc5_key_timeout = ir_rc5_key_timeout;
+ ir->rc5_remote_gap = ir_rc5_remote_gap;
+ }
+
+ /* all done */
+ dev->remote = ir;
+
input_register_device(ir->dev);
return 0;
}
@@ -353,6 +386,49 @@ void saa7134_set_i2c_ir(struct saa7134_d
}
}
+
+static int saa7134_rc5_irq(struct saa7134_dev *btv)
+{
+ struct card_ir *ir = btv->remote;
+ struct timeval tv;
+ u32 gap;
+ unsigned long current_jiffies, timeout;
+
+ /* get time of bit */
+ current_jiffies = jiffies;
+ do_gettimeofday(&tv);
+
+ /* avoid overflow with gap >1s */
+ if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+ gap = 200000;
+ } else {
+ gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+ tv.tv_usec - ir->base_time.tv_usec;
+ }
+
+ /* active code => add bit */
+ if (ir->active) {
+ /* only if in the code (otherwise spurious IRQ or timer
+ late) */
+ if (ir->last_bit < 28) {
+ ir->last_bit = (gap - ir_rc5_remote_gap / 2) /
+ ir_rc5_remote_gap;
+ ir->code |= 1 << ir->last_bit;
+ }
+ /* starting new code */
+ } else {
+ ir->active = 1;
+ ir->code = 0;
+ ir->base_time = tv;
+ ir->last_bit = 0;
+
+ timeout = current_jiffies + (500 + 30 * HZ) / 1000;
+ mod_timer(&ir->timer_end, timeout);
+ }
+
+ return 1;
+}
+
/* ----------------------------------------------------------------------
* Local variables:
* c-basic-offset: 8
diff -r 12f0f1ce18b1 linux/drivers/media/video/saa7134/saa7134.h
--- a/linux/drivers/media/video/saa7134/saa7134.h Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/drivers/media/video/saa7134/saa7134.h Thu Sep 28 22:28:14 2006 +0200
@@ -425,20 +425,6 @@ struct saa7134_dmasound {
#endif
};
-/* IR input */
-struct saa7134_ir {
- struct input_dev *dev;
- struct ir_input_state ir;
- char name[32];
- char phys[32];
- u32 mask_keycode;
- u32 mask_keydown;
- u32 mask_keyup;
- int polling;
- u32 last_gpio;
- struct timer_list timer;
-};
-
/* ts/mpeg status */
struct saa7134_ts {
/* TS capture */
@@ -478,7 +464,7 @@ struct saa7134_dev {
/* infrared remote */
int has_remote;
- struct saa7134_ir *remote;
+ struct card_ir *remote;
/* pci i/o */
char name[32];
@@ -715,6 +701,7 @@ void saa7134_input_irq(struct saa7134_de
void saa7134_input_irq(struct saa7134_dev *dev);
void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
+
/*
* Local variables:
* c-basic-offset: 8
diff -r 12f0f1ce18b1 linux/include/media/ir-common.h
--- a/linux/include/media/ir-common.h Thu Sep 28 14:03:26 2006 -0300
+++ b/linux/include/media/ir-common.h Thu Sep 28 22:28:54 2006 +0200
@@ -35,6 +35,14 @@
#define IR_KEYCODE(tab,code) (((unsigned)code < IR_KEYTAB_SIZE) \
? tab[code] : KEY_RESERVED)
+extern int ir_rc5_remote_gap;
+extern int ir_rc5_key_timeout;
+
+#define RC5_START(x) (((x)>>12)&3)
+#define RC5_TOGGLE(x) (((x)>>11)&1)
+#define RC5_ADDR(x) (((x)>>6)&31)
+#define RC5_INSTR(x) ((x)&63)
+
struct ir_input_state {
/* configuration */
int ir_type;
@@ -47,6 +55,40 @@ struct ir_input_state {
int keypressed; /* current state */
};
+/* this was saa7134_ir and bttv_ir, moved here for
+ * rc5 decoding. */
+struct card_ir {
+ struct input_dev *dev;
+ struct ir_input_state ir;
+ char name[32];
+ char phys[32];
+
+ /* Usual gpio signalling */
+
+ u32 mask_keycode;
+ u32 mask_keydown;
+ u32 mask_keyup;
+ u32 polling;
+ u32 last_gpio;
+ int shift_by;
+ int start; // What should RC5_START() be
+ int addr; // What RC5_ADDR() should be.
+ int rc5_key_timeout;
+ int rc5_remote_gap;
+ struct work_struct work;
+ struct timer_list timer;
+
+ /* RC5 gpio */
+ u32 rc5_gpio;
+ struct timer_list timer_end; /* timer_end for code completion */
+ struct timer_list timer_keyup; /* timer_end for key release */
+ u32 last_rc5; /* last good rc5 code */
+ u32 last_bit; /* last raw bit seen */
+ u32 code; /* raw code under construction */
+ struct timeval base_time; /* time of last seen code */
+ int active; /* building raw code */
+};
+
void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
int ir_type, IR_KEYTAB_TYPE *ir_codes);
void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir);
@@ -56,6 +98,10 @@ int ir_dump_samples(u32 *samples, int c
int ir_dump_samples(u32 *samples, int count);
int ir_decode_biphase(u32 *samples, int count, int low, int high);
int ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
+
+u32 ir_rc5_decode(unsigned int code);
+void ir_rc5_timer_end(unsigned long data);
+void ir_rc5_timer_keyup(unsigned long data);
/* Keymaps to be used by other modules */
@@ -92,6 +138,7 @@ extern IR_KEYTAB_TYPE ir_codes_npgtech[I
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_asus_pc39[IR_KEYTAB_SIZE];
#endif
-- video4linux discussion Unsubscribe mailto:video4linux-list-request@xxxxxxxxxx?subject=unsubscribe https://www.redhat.com/mailman/listinfo/video4linux-list
[Linux Media] [Older V4L] [Linux DVB] [Video Disk Recorder] [Linux Kernel] [Asterisk] [Photo] [DCCP] [Netdev] [Xorg] [Util Linux NG] [Xfree86] [Free Photo Albums] [Fedora Users] [Fedora Women] [ALSA Users] [ALSA Devel] [SSH] [DVB Maintainers] [Linux USB] [Yosemite Information]
![]() |
![]() |