diff -r 229f6179e4c7 linux/drivers/media/video/cx88/Makefile --- a/linux/drivers/media/video/cx88/Makefile Mon Jul 17 16:34:27 2006 -0300 +++ b/linux/drivers/media/video/cx88/Makefile Fri Aug 11 21:47:24 2006 -0400 @@ -12,6 +12,7 @@ EXTRA_CFLAGS += -Idrivers/media/video EXTRA_CFLAGS += -Idrivers/media/video EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends +EXTRA_CFLAGS += -DUSE_LIRC -I$(LIRC_HOME) extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1 diff -r 229f6179e4c7 linux/drivers/media/video/cx88/cx88-input.c --- a/linux/drivers/media/video/cx88/cx88-input.c Mon Jul 17 16:34:27 2006 -0300 +++ b/linux/drivers/media/video/cx88/cx88-input.c Sat Aug 12 11:45:13 2006 -0400 @@ -32,6 +32,11 @@ #include "compat.h" #include "cx88.h" #include +#ifdef USE_LIRC +#include +#include +#include +#endif /* ---------------------------------------------------------------------- */ @@ -57,6 +62,10 @@ struct cx88_IR { u32 mask_keycode; u32 mask_keydown; u32 mask_keyup; +#ifdef USE_LIRC + struct lirc_buffer rbuf; + int lirc_minor; +#endif }; static int ir_debug = 0; @@ -66,6 +75,62 @@ MODULE_PARM_DESC(ir_debug, "enable debug #define ir_dprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg) +/* ---------------------------------------------------------------------- */ +#ifdef USE_LIRC +// LIRC stuff +#define LIRC_DRIVER_NAME "lirc_cx88" +#define RBUF_LEN 256 + +static int lirc_use_count = 0; + +static int set_use_inc(void* data) +{ + lirc_use_count++; + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void* data) +{ + lirc_use_count--; + MOD_DEC_USE_COUNT; +} + +static void write_lirc_code(struct cx88_IR *ir, u32 data) +{ + u8 data1[4]; + + if(lirc_buffer_full(&ir->rbuf)) /* no new signals will be accepted */ + { + ir_dprintk("LIRC buffer overrun\n"); + return; + } + data1[0] = data >> 24; + data1[1] = (data >> 16) & 0xFF; + data1[2] = (data >> 8) & 0xFF; + data1[3] = data & 0xFF; + _lirc_buffer_write_1(&ir->rbuf, (void *)&data1); + wake_up_interruptible(&ir->rbuf.wait_poll); +} + +static struct lirc_plugin plugin = { + name: LIRC_DRIVER_NAME, + minor: -1, + features: LIRC_CAN_REC_LIRCCODE, + code_length: 32, + sample_rate: 0, + data: NULL, + add_to_buf: NULL, + get_queue: NULL, + rbuf: NULL, + set_use_inc: set_use_inc, + set_use_dec: set_use_dec, + ioctl: NULL, + fops: NULL, + owner: THIS_MODULE, +}; + +#endif // USE_LIRC /* ---------------------------------------------------------------------- */ static void cx88_ir_handle_key(struct cx88_IR *ir) @@ -188,6 +253,7 @@ int cx88_ir_init(struct cx88_core *core, case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_HVR1100: + case CX88_BOARD_PCHDTV_HD5500: ir_codes = ir_codes_hauppauge_new; ir_type = IR_TYPE_RC5; ir->sampling = 1; @@ -262,7 +328,18 @@ int cx88_ir_init(struct cx88_core *core, input_free_device(input_dev); return -ENODEV; } - +#ifdef USE_LIRC + plugin.rbuf = &ir->rbuf; + plugin.data = (void *)ir; + ir->lirc_minor = lirc_register_plugin(&plugin); + + if (ir->lirc_minor >= 0) + { + /* Init read buffer. */ + if (lirc_buffer_init(&ir->rbuf, sizeof(u32), RBUF_LEN) < 0) + return -ENOMEM; + } +#endif /* init input device */ snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", cx88_boards[core->board].name); @@ -328,6 +405,13 @@ int cx88_ir_fini(struct cx88_core *core) } input_unregister_device(ir->input); +#ifdef USE_LIRC + if (ir->lirc_minor >= 0) + { + lirc_unregister_plugin(ir->lirc_minor); + lirc_buffer_free(&ir->rbuf); + } +#endif kfree(ir); /* done */ @@ -416,6 +500,34 @@ void cx88_ir_irq(struct cx88_core *core) ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode); ir->release = jiffies + msecs_to_jiffies(120); break; +#ifdef USE_LIRC + case CX88_BOARD_PCHDTV_HD5500: + // first try as RC-5 + ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); + if ((ircode & 0xffff2000) == 0x2000) + { + ir_dprintk("biphase decoded: %x\n", ircode); + } + else + { + // try pulse-distance + ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); + + if (ircode == 0xffffffff) /* decoding error */ + break; + + ir_dprintk("pulse distance decoded: %x\n", ircode); + // ircode = 0 is "repeat code" + } + + // write the RC5 code to LIRC + write_lirc_code(ir, ircode); + // doesn't write anything to input driver, though input + // driver is still set up. Should really split the LIRC + // stuff into a separate, alternative module, but this + // will work as a one-off solution + break; +#endif } ir->scount = 0;