static void cx88_ir_handle_key(struct cx88_IR *ir)
{
struct cx88_core *core = ir->core;
- u32 gpio, data;
+ u32 gpio, data, auxgpio;
/* read gpio value */
gpio = cx_read(ir->gpio_addr);
+ if (core->board == CX88_BOARD_NPGTECH_REALTV_TOP10FM) {
+ /* This board apparently uses a combination of 2 GPIO
+ to represent the keys. Additionally, the second GPIO
+ can be used for parity.
+
+ Example:
+
+ for key "5"
+ gpio = 0x758, auxgpio = 0xe5 or 0xf5
+ for key "Power"
+ gpio = 0x758, auxgpio = 0xed or 0xfd
+ */
+
+ auxgpio = cx_read(MO_GP1_IO);
+ /* Take out the parity part */
+ gpio=(gpio & 0x7fd) + (auxgpio & 0xef);
+ } else
+ auxgpio = gpio;
+
if (ir->polling) {
- if (ir->last_gpio == gpio)
+ if (ir->last_gpio == auxgpio)
return;
- ir->last_gpio = gpio;
+ ir->last_gpio = auxgpio;
}
/* extract data */
(gpio & ir->mask_keydown) ? " down" : "",
(gpio & ir->mask_keyup) ? " up" : "");
- if (ir->mask_keydown) {
+ if (ir->core->board == CX88_BOARD_NORWOOD_MICRO) {
+ u32 gpio_key = cx_read(MO_GP0_IO);
+
+ data = (data << 4) | ((gpio_key & 0xf0) >> 4);
+
+ ir_input_keydown(ir->input, &ir->ir, data, data);
+ ir_input_nokey(ir->input, &ir->ir);
+
+ } else if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown) {
ir_input_keydown(ir->input, &ir->ir, data, data);
schedule_work(&ir->work);
}
-static void cx88_ir_work(void *data)
+static void cx88_ir_work(struct work_struct *work)
{
- struct cx88_IR *ir = data;
+ struct cx88_IR *ir = container_of(work, struct cx88_IR, work);
unsigned long timeout;
cx88_ir_handle_key(ir);
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_HVR1100:
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
ir_codes = ir_codes_hauppauge_new;
ir_type = IR_TYPE_RC5;
ir->sampling = 1;
break;
+ case CX88_BOARD_WINFAST_DTV2000H:
+ ir_codes = ir_codes_winfast;
+ ir->gpio_addr = MO_GP0_IO;
+ ir->mask_keycode = 0x8f8;
+ ir->mask_keyup = 0x100;
+ ir->polling = 50; /* ms */
+ break;
case CX88_BOARD_WINFAST2000XP_EXPERT:
ir_codes = ir_codes_winfast;
ir->gpio_addr = MO_GP0_IO;
ir->mask_keydown = 0x02;
ir->polling = 5; /* ms */
break;
- case CX88_BOARD_PROLINK_PLAYTVPVR:
+ case CX88_BOARD_PROLINK_PLAYTVPVR:
case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
ir_codes = ir_codes_pixelview;
ir->gpio_addr = MO_GP1_IO;
ir_type = IR_TYPE_PD;
ir->sampling = 0xff00; /* address */
break;
+ case CX88_BOARD_NORWOOD_MICRO:
+ ir_codes = ir_codes_norwood;
+ ir->gpio_addr = MO_GP1_IO;
+ ir->mask_keycode = 0x0e;
+ ir->mask_keyup = 0x80;
+ ir->polling = 50; /* ms */
+ break;
+ case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
+ ir_codes = ir_codes_npgtech;
+ ir->gpio_addr = MO_GP0_IO;
+ ir->mask_keycode = 0xfa;
+ ir->polling = 50; /* ms */
+ break;
}
if (NULL == ir_codes) {
core->ir = ir;
if (ir->polling) {
- INIT_WORK(&ir->work, cx88_ir_work, ir);
+ INIT_WORK(&ir->work, cx88_ir_work);
init_timer(&ir->timer);
ir->timer.function = ir_timer;
ir->timer.data = (unsigned long)ir;
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_HVR1100:
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
ir_dprintk("biphase decoded: %x\n", ircode);
if ((ircode & 0xfffff000) != 0x3000)