static void smi_ir_decode(struct work_struct *work) { struct smi_rc *ir = container_of(work, struct smi_rc, work); struct smi_dev *dev = ir->dev; struct rc_dev *rc_dev = ir->rc_dev; u32 dwIRControl, dwIRData, dwIRCode, scancode; u8 index, ucIRCount, readLoop, rc5_command, rc5_system, toggle; dwIRControl = smi_read(IR_Init_Reg); if (dwIRControl & rbIRVld) { ucIRCount = (u8) smi_read(IR_Data_Cnt); if (ucIRCount < 4) goto end_ir_decode; readLoop = ucIRCount/4; if (ucIRCount % 4) readLoop += 1; for (index = 0; index < readLoop; index++) { dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index*4)); ir->irData[index*4 + 0] = (u8)(dwIRData); ir->irData[index*4 + 1] = (u8)(dwIRData >> 8); ir->irData[index*4 + 2] = (u8)(dwIRData >> 16); ir->irData[index*4 + 3] = (u8)(dwIRData >> 24); } dwIRCode = smi_decode_rc5(ir->irData, ucIRCount); if (dwIRCode != 0xFFFFFFFF) { rc5_command = dwIRCode & 0x3F; rc5_system = (dwIRCode & 0x7C0) >> 6; toggle = (dwIRCode & 0x800) ? 1 : 0; scancode = rc5_system << 8 | rc5_command; rc_keydown(rc_dev, RC_TYPE_RC5, scancode, toggle); }
static void tm6000_ir_keydown(struct tm6000_IR *ir, const char *buf, unsigned int len) { u8 device, command; u32 scancode; enum rc_proto protocol; if (len < 1) return; command = buf[0]; device = (len > 1 ? buf[1] : 0x0); switch (ir->rc_proto) { case RC_PROTO_BIT_RC5: protocol = RC_PROTO_RC5; scancode = RC_SCANCODE_RC5(device, command); break; case RC_PROTO_BIT_NEC: protocol = RC_PROTO_NEC; scancode = RC_SCANCODE_NEC(device, command); break; default: protocol = RC_PROTO_OTHER; scancode = RC_SCANCODE_OTHER(device << 8 | command); break; } dprintk(1, "%s, protocol: 0x%04x, scancode: 0x%08x\n", __func__, protocol, scancode); rc_keydown(ir->rc, protocol, scancode, 0); }
static int m920x_rc_core_query(struct dvb_usb_device *d) { int ret = 0; u8 *rc_state; int state; rc_state = kmalloc(2, GFP_KERNEL); if (!rc_state) return -ENOMEM; if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, &rc_state[0], 1)) != 0) goto out; if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, &rc_state[1], 1)) != 0) goto out; deb("state=0x%02x keycode=0x%02x\n", rc_state[0], rc_state[1]); m920x_parse_rc_state(d, rc_state[0], &state); if (state == REMOTE_NO_KEY_PRESSED) rc_keyup(d->rc_dev); else if (state == REMOTE_KEY_REPEAT) rc_repeat(d->rc_dev); else rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, rc_state[1], 0); out: kfree(rc_state); return ret; }
static int anysee_rc_query(struct dvb_usb_device *d) { u8 buf[] = {CMD_GET_IR_CODE}; u8 ircode[2]; int ret; /* Remote controller is basic NEC using address byte 0x08. Anysee device RC query returns only two bytes, status and code, address byte is dropped. Also it does not return any value for NEC RCs having address byte other than 0x08. Due to that, we cannot use that device as standard NEC receiver. It could be possible make hack which reads whole code directly from device memory... */ ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode)); if (ret) return ret; if (ircode[0]) { deb_rc("%s: key pressed %02x\n", __func__, ircode[1]); rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0); } return 0; }
/* remote control stuff (does not work with my box) */ static int az6007_rc_query(struct dvb_usb_device *d) { struct az6007_device_state *st = d_to_priv(d); unsigned code; az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); if (st->data[1] == 0x44) return 0; if ((st->data[3] ^ st->data[4]) == 0xff) { if ((st->data[1] ^ st->data[2]) == 0xff) code = RC_SCANCODE_NEC(st->data[1], st->data[3]); else code = RC_SCANCODE_NECX(st->data[1] << 8 | st->data[2], st->data[3]); } else { code = RC_SCANCODE_NEC32(st->data[1] << 24 | st->data[2] << 16 | st->data[3] << 8 | st->data[4]); } rc_keydown(d->rc_dev, RC_TYPE_NEC, code, st->data[5]); return 0; }
static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress) { struct dvb_usb_device *d = adap->dev; deb_info(1, "INT Key Keypress =%04x", keypress); if (keypress > 0) rc_keydown(d->rc_dev, keypress, 0); return 0; }
static void bttv_rc5_timer_end(unsigned long data) { struct bttv_ir *ir = (struct bttv_ir *)data; struct timeval tv; u32 gap; u32 rc5 = 0; /* get time */ 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; } /* signal we're ready to start a new code */ ir->active = false; /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ if (gap < 28000) { dprintk(KERN_INFO DEVNAME ": spurious timer_end\n"); return; } if (ir->last_bit < 20) { /* ignore spurious codes (caused by light/other remotes) */ dprintk(KERN_INFO DEVNAME ": short code: %x\n", ir->code); } else { ir->code = (ir->code << ir->shift_by) | 1; rc5 = bttv_rc5_decode(ir->code); /* two start bits? */ if (RC5_START(rc5) != ir->start) { printk(KERN_INFO DEVNAME ":" " 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 */ rc_keydown(ir->dev, instr, toggle); dprintk(KERN_INFO DEVNAME ":" " instruction %x, toggle %x\n", instr, toggle); } } }
static void bttv_rc5_timer_end(unsigned long data) { struct bttv_ir *ir = (struct bttv_ir *)data; ktime_t tv; u32 gap, rc5, scancode; u8 toggle, command, system; /* get time */ tv = ktime_get(); gap = ktime_to_us(ktime_sub(tv, ir->base_time)); /* avoid overflow with gap >1s */ if (gap > USEC_PER_SEC) { gap = 200000; } /* signal we're ready to start a new code */ ir->active = false; /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ if (gap < 28000) { dprintk("spurious timer_end\n"); return; } if (ir->last_bit < 20) { /* ignore spurious codes (caused by light/other remotes) */ dprintk("short code: %x\n", ir->code); return; } ir->code = (ir->code << ir->shift_by) | 1; rc5 = bttv_rc5_decode(ir->code); toggle = RC5_TOGGLE(rc5); system = RC5_ADDR(rc5); command = RC5_INSTR(rc5); switch (RC5_START(rc5)) { case 0x3: break; case 0x2: command += 0x40; break; default: return; } scancode = RC_SCANCODE_RC5(system, command); rc_keydown(ir->dev, RC_TYPE_RC5, scancode, toggle); dprintk("scancode %x, toggle %x\n", scancode, toggle); }
static ssize_t user_rc_input_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { int ret; struct user_rc_input_dev *input_dev = file->private_data; __u8 *buf; buf = kmalloc(count * sizeof(__u8), GFP_KERNEL); if (!buf) { dev_err(input_dev->dev, "kmalloc failed...Insufficient memory\n"); ret = -ENOMEM; goto out; } if (copy_from_user(buf, buffer, count)) { dev_err(input_dev->dev, "Copy from user failed\n"); ret = -EFAULT; goto out_free; } switch (buf[0]) { case USER_CONTROL_PRESSED: dev_dbg(input_dev->dev, "user controlled" " pressed 0x%x\n", buf[1]); rc_keydown(input_dev->rcdev, buf[1], 0); break; case USER_CONTROL_REPEATED: dev_dbg(input_dev->dev, "user controlled" " repeated 0x%x\n", buf[1]); rc_repeat(input_dev->rcdev); break; case USER_CONTROL_RELEASED: dev_dbg(input_dev->dev, "user controlled" " released 0x%x\n", buf[1]); rc_keyup(input_dev->rcdev); break; } out_free: kfree(buf); out: return ret; }
static int dvbsky_rc_query(struct dvb_usb_device *d) { u32 code = 0xffff, scancode; u8 rc5_command, rc5_system; u8 obuf[2], ibuf[2], toggle; int ret; obuf[0] = 0x10; ret = dvbsky_usb_generic_rw(d, obuf, 1, ibuf, 2); if (ret == 0) code = (ibuf[0] << 8) | ibuf[1]; if (code != 0xffff) { dev_dbg(&d->udev->dev, "rc code: %x\n", code); rc5_command = code & 0x3F; rc5_system = (code & 0x7C0) >> 6; toggle = (code & 0x800) ? 1 : 0; scancode = rc5_system << 8 | rc5_command; rc_keydown(d->rc_dev, RC_PROTO_RC5, scancode, toggle); }
/* static void smi_ir_decode(unsigned long data) */ static void smi_ir_decode(struct work_struct *work) { /* struct smi_rc *ir = (struct smi_rc *)data; */ struct smi_rc *ir = container_of(work, struct smi_rc, work); struct smi_dev *dev = ir->dev; struct rc_dev *rc_dev = ir->rc_dev; /* int ret; struct ir_raw_event ev; */ u32 dwIRControl, dwIRData, dwIRCode, scancode; u8 index, ucIRCount, readLoop, rc5_command, rc5_system, toggle; dwIRControl = smi_read(IR_Init_Reg); /*dprintk("IR_Init_Reg = 0x%08x\n", dwIRControl);*/ if( dwIRControl & rbIRVld) { ucIRCount = (u8) smi_read(IR_Data_Cnt); /*dprintk("ir data count=%d\n", ucIRCount);*/ if(ucIRCount < 4) { goto end_ir_decode; } readLoop = ucIRCount/4; if(ucIRCount % 4) readLoop += 1; for(index = 0; index < readLoop; index++) { dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index*4)); /*dprintk("ir data[%d] = 0x%08x\n", index, dwIRData);*/ ir->irData[index*4 + 0] = (u8)(dwIRData); ir->irData[index*4 + 1] = (u8)(dwIRData >> 8); ir->irData[index*4 + 2] = (u8)(dwIRData >> 16); ir->irData[index*4 + 3] = (u8)(dwIRData >> 24); } dwIRCode = smi_decode_rc5(ir->irData, ucIRCount); if (dwIRCode != 0xFFFFFFFF) { dprintk("rc code: %x \n", dwIRCode); rc5_command = dwIRCode & 0x3F; rc5_system = (dwIRCode & 0x7C0) >> 6; toggle = (dwIRCode & 0x800) ? 1 : 0; scancode = rc5_system << 8 | rc5_command; rc_keydown(rc_dev, scancode, toggle); }
static void tm6000_ir_handle_key(struct work_struct *work) { struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); struct tm6000_core *dev = ir->dev; struct tm6000_ir_poll_result poll_result; int rc; u8 buf[2]; if (ir->wait) return; dprintk(3, "%s\n",__func__); rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 2); if (rc < 0) return; if (rc > 1) poll_result.rc_data = buf[0] | buf[1] << 8; else poll_result.rc_data = buf[0]; /* Check if something was read */ if ((poll_result.rc_data & 0xff) == 0xff) { if (!ir->pwled) { tm6000_flash_led(dev, 1); ir->pwled = 1; } return; } dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data); rc_keydown(ir->rc, poll_result.rc_data, 0); tm6000_flash_led(dev, 0); ir->pwled = 0; /* Re-schedule polling */ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); }
/* IR */ static int tt3650_rc_query(struct dvb_usb_device *d) { int ret; u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */ struct ttusb2_state *st = d->priv; ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx)); if (ret != 0) return ret; if (rx[8] & 0x01) { /* got a "press" event */ st->last_rc_key = (rx[3] << 8) | rx[2]; deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]); rc_keydown(d->rc_dev, st->last_rc_key, 0); } else if (st->last_rc_key) { rc_keyup(d->rc_dev); st->last_rc_key = 0; } return 0; }
static void tm6000_ir_urb_received(struct urb *urb) { struct tm6000_core *dev = urb->context; struct tm6000_IR *ir = dev->ir; struct tm6000_ir_poll_result poll_result; char *buf; dprintk(2, "%s\n",__func__); if (urb->status < 0 || urb->actual_length <= 0) { printk(KERN_INFO "tm6000: IR URB failure: status: %i, length %i\n", urb->status, urb->actual_length); ir->submit_urb = 1; schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY)); return; } buf = urb->transfer_buffer; if (ir_debug) print_hex_dump(KERN_DEBUG, "tm6000: IR data: ", DUMP_PREFIX_OFFSET,16, 1, buf, urb->actual_length, false); poll_result.rc_data = buf[0]; if (urb->actual_length > 1) poll_result.rc_data |= buf[1] << 8; dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data); rc_keydown(ir->rc, poll_result.rc_data, 0); usb_submit_urb(urb, GFP_ATOMIC); /* * Flash the led. We can't do it here, as it is running on IRQ context. * So, use the scheduler to do it, in a few ms. */ ir->pwled = 2; schedule_delayed_work(&ir->work, msecs_to_jiffies(10)); }
/* remote control stuff (does not work with my box) */ static int az6007_rc_query(struct dvb_usb_device *d) { struct az6007_device_state *st = d->priv; unsigned code = 0; az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); if (st->data[1] == 0x44) return 0; if ((st->data[1] ^ st->data[2]) == 0xff) code = st->data[1]; else code = st->data[1] << 8 | st->data[2]; if ((st->data[3] ^ st->data[4]) == 0xff) code = code << 8 | st->data[3]; else code = code << 16 | st->data[3] << 8 | st->data[4]; rc_keydown(d->rc_dev, code, st->data[5]); return 0; }
/** * ir_sanyo_decode() - Decode one SANYO pulse or space * @dev: the struct rc_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct sanyo_dec *data = &dev->raw->sanyo; u32 scancode; u8 address, command, not_command; if (!(dev->raw->enabled_protocols & RC_BIT_SANYO)) return 0; if (!is_timing_event(ev)) { if (ev.reset) { IR_dprintk(1, "SANYO event reset received. reset to state 0\n"); data->state = STATE_INACTIVE; } return 0; } IR_dprintk(2, "SANYO decode started at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) { data->count = 0; data->state = STATE_HEADER_SPACE; return 0; } break; case STATE_HEADER_SPACE: if (ev.pulse) break; if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; } break; case STATE_BIT_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2)) break; data->state = STATE_BIT_SPACE; return 0; case STATE_BIT_SPACE: if (ev.pulse) break; if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) { if (!dev->keypressed) { IR_dprintk(1, "SANYO discarding last key repeat: event after key up\n"); } else { rc_repeat(dev); IR_dprintk(1, "SANYO repeat last key\n"); data->state = STATE_INACTIVE; } return 0; } data->bits <<= 1; if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2)) data->bits |= 1; else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2)) break; data->count++; if (data->count == SANYO_NBITS) data->state = STATE_TRAILER_PULSE; else data->state = STATE_BIT_PULSE; return 0; case STATE_TRAILER_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, SANYO_TRAILER_PULSE, SANYO_UNIT / 2)) break; data->state = STATE_TRAILER_SPACE; return 0; case STATE_TRAILER_SPACE: if (ev.pulse) break; if (!geq_margin(ev.duration, SANYO_TRAILER_SPACE, SANYO_UNIT / 2)) break; address = bitrev16((data->bits >> 29) & 0x1fff) >> 3; /* not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; */ command = bitrev8((data->bits >> 8) & 0xff); not_command = bitrev8((data->bits >> 0) & 0xff); if ((command ^ not_command) != 0xff) { IR_dprintk(1, "SANYO checksum error: received 0x%08Lx\n", data->bits); data->state = STATE_INACTIVE; return 0; } scancode = address << 8 | command; IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode); rc_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } IR_dprintk(1, "SANYO decode failed at count %d state %d (%uus %s)\n", data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
static int rtl2831u_rc_query(struct dvb_usb_device *d) { int ret, i; struct rtl28xxu_priv *priv = d->priv; u8 buf[5]; u32 rc_code; struct rtl28xxu_reg_val rc_nec_tab[] = { { 0x3033, 0x80 }, { 0x3020, 0x43 }, { 0x3021, 0x16 }, { 0x3022, 0x16 }, { 0x3023, 0x5a }, { 0x3024, 0x2d }, { 0x3025, 0x16 }, { 0x3026, 0x01 }, { 0x3028, 0xb0 }, { 0x3029, 0x04 }, { 0x302c, 0x88 }, { 0x302e, 0x13 }, { 0x3030, 0xdf }, { 0x3031, 0x05 }, }; /* init remote controller */ if (!priv->rc_active) { for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) { ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg, rc_nec_tab[i].val); if (ret) goto err; } priv->rc_active = true; } ret = rtl2831_rd_regs(d, SYS_IRRC_RP, buf, 5); if (ret) goto err; if (buf[4] & 0x01) { if (buf[2] == (u8) ~buf[3]) { if (buf[0] == (u8) ~buf[1]) { /* NEC standard (16 bit) */ rc_code = buf[0] << 8 | buf[2]; } else { /* NEC extended (24 bit) */ rc_code = buf[0] << 16 | buf[1] << 8 | buf[2]; } } else { /* NEC full (32 bit) */ rc_code = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; } rc_keydown(d->rc_dev, rc_code, 0); ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1); if (ret) goto err; /* repeated intentionally to avoid extra keypress */ ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1); if (ret) goto err; } return ret; err: dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); return ret; }
int mtk_ir_mouse_proc_key(u32 scancode, struct mtk_rc_core *p_mtk_rc_core) { struct input_dev *p_devmouse = p_mtk_rc_core->p_devmouse; struct mtk_ir_core_platform_data *pdata = p_mtk_rc_core->dev_current->dev.platform_data; struct rc_dev *rcdev = p_mtk_rc_core->rcdev; struct mtk_ir_mouse_code *p_mousecode = NULL; ASSERT(p_devmouse != NULL); ASSERT(pdata != NULL); p_mousecode = &(pdata->mouse_code); if (scancode == p_mousecode->scanleft) { if (!(rcdev->keypressed)) /* last key was released, this is the first time switch code down. */ { IR_LOG_ALWAYS("MOUSE X_LEFT PRESS\n"); input_report_rel(p_devmouse, REL_X, -x_small_step); /* first time small step */ input_report_rel(p_devmouse, REL_Y, 0); } else { IR_LOG_ALWAYS("MOUSE X_LEFT REPEAT\n"); input_report_rel(p_devmouse, REL_X, -x_large_step); /* repeat large step */ input_report_rel(p_devmouse, REL_Y, 0); } } else if (scancode == p_mousecode->scanright) { if (!(rcdev->keypressed)) /* last key was released, this is the first time switch code down. */ { IR_LOG_ALWAYS("MOUSE X_RIGHT PRESS\n"); input_report_rel(p_devmouse, REL_X, x_small_step); /* first time small step */ input_report_rel(p_devmouse, REL_Y, 0); } else { IR_LOG_ALWAYS("MOUSE X_RIGHT REPEAT\n"); input_report_rel(p_devmouse, REL_X, x_large_step); /* repeat large step */ input_report_rel(p_devmouse, REL_Y, 0); } } else if (scancode == p_mousecode->scanup) { if (!(rcdev->keypressed)) /* last key was released, this is the first time switch code down. */ { IR_LOG_ALWAYS("MOUSE Y_UP PRESS\n"); input_report_rel(p_devmouse, REL_X, 0); /* first time small step */ input_report_rel(p_devmouse, REL_Y, -y_small_step); } else { IR_LOG_ALWAYS("MOUSE Y_UP REPEAT\n"); input_report_rel(p_devmouse, REL_X, 0); /* repeat large step */ input_report_rel(p_devmouse, REL_Y, -y_large_step); } } else if (scancode == p_mousecode->scandown) { if (!(rcdev->keypressed)) /* last key was released, this is the first time switch code down. */ { IR_LOG_ALWAYS("MOUSE Y_DOWN PRESS\n"); input_report_rel(p_devmouse, REL_X, 0); /* first time small step */ input_report_rel(p_devmouse, REL_Y, y_small_step); } else { IR_LOG_ALWAYS("MOUSE Y_DOWN REPEAT\n"); input_report_rel(p_devmouse, REL_X, 0); /* repeat large step */ input_report_rel(p_devmouse, REL_Y, y_large_step); } } else if (scancode == p_mousecode->scanenter) { if (!(rcdev->keypressed)) /* last key was released, this is the first time switch code down. */ { IR_LOG_ALWAYS("MOUSE BTN_LEFT PRESS\n"); input_report_key(p_devmouse, BTN_LEFT, 1); input_report_rel(p_devmouse, REL_X, 0); input_report_rel(p_devmouse, REL_Y, 0); input_sync(p_devmouse); IR_LOG_ALWAYS("MOUSE BTN_LEFT RELEASE\n"); input_report_key(p_devmouse, BTN_LEFT, 0); input_report_rel(p_devmouse, REL_X, 0); input_report_rel(p_devmouse, REL_Y, 0); } else { } } /* another code as EV_KEY to send */ else { return 0; } rc_keydown(rcdev, 0xffff, 0); input_sync(p_devmouse); return 1; }
/** * ir_rc6_decode() - Decode one RC6 pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc6_dec *data = &dev->raw->rc6; u32 scancode; u8 toggle; enum rc_proto protocol; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) goto out; again: IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; /* Note: larger margin on first pulse since each RC6_UNIT is quite short and some hardware takes some time to adjust to the signal */ if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT)) break; data->state = STATE_PREFIX_SPACE; data->count = 0; return 0; case STATE_PREFIX_SPACE: if (ev.pulse) break; if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2)) break; data->state = STATE_HEADER_BIT_START; data->header = 0; return 0; case STATE_HEADER_BIT_START: if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) break; data->header <<= 1; if (ev.pulse) data->header |= 1; data->count++; data->state = STATE_HEADER_BIT_END; return 0; case STATE_HEADER_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == RC6_HEADER_NBITS) data->state = STATE_TOGGLE_START; else data->state = STATE_HEADER_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_TOGGLE_START: if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2)) break; data->toggle = ev.pulse; data->state = STATE_TOGGLE_END; return 0; case STATE_TOGGLE_END: if (!is_transition(&ev, &dev->raw->prev_ev) || !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) break; if (!(data->header & RC6_STARTBIT_MASK)) { IR_dprintk(1, "RC6 invalid start bit\n"); break; } data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_TOGGLE_END); data->count = 0; data->body = 0; switch (rc6_mode(data)) { case RC6_MODE_0: data->wanted_bits = RC6_0_NBITS; break; case RC6_MODE_6A: data->wanted_bits = RC6_6A_NBITS; break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } goto again; case STATE_BODY_BIT_START: if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) { /* Discard LSB's that won't fit in data->body */ if (data->count++ < CHAR_BIT * sizeof data->body) { data->body <<= 1; if (ev.pulse) data->body |= 1; } data->state = STATE_BODY_BIT_END; return 0; } else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse && geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) { data->state = STATE_FINISHED; goto again; } break; case STATE_BODY_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_FINISHED: if (ev.pulse) break; switch (rc6_mode(data)) { case RC6_MODE_0: scancode = data->body; toggle = data->toggle; protocol = RC_PROTO_RC6_0; IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", scancode, toggle); break; case RC6_MODE_6A: if (data->count > CHAR_BIT * sizeof data->body) { IR_dprintk(1, "RC6 too many (%u) data bits\n", data->count); goto out; } scancode = data->body; switch (data->count) { case 20: protocol = RC_PROTO_RC6_6A_20; toggle = 0; break; case 24: protocol = RC_PROTO_RC6_6A_24; toggle = 0; break; case 32: if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { protocol = RC_PROTO_RC6_MCE; toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); scancode &= ~RC6_6A_MCE_TOGGLE_MASK; } else { protocol = RC_PROTO_RC6_6A_32; toggle = 0; } break; default: IR_dprintk(1, "RC6(6A) unsupported length\n"); goto out; } IR_dprintk(1, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n", protocol, scancode, toggle); break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } rc_keydown(dev, protocol, scancode, toggle); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc5_sz_dec *data = &dev->raw->rc5_sz; u8 toggle, command, system; u32 scancode; if (!(dev->raw->enabled_protocols & RC_TYPE_RC5_SZ)) return 0; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) goto out; again: IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; data->state = STATE_BIT_START; data->count = 1; data->wanted_bits = RC5_SZ_NBITS; decrease_duration(&ev, RC5_BIT_START); goto again; case STATE_BIT_START: if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) break; data->bits <<= 1; if (!ev.pulse) data->bits |= 1; data->count++; data->state = STATE_BIT_END; return 0; case STATE_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else data->state = STATE_BIT_START; decrease_duration(&ev, RC5_BIT_END); goto again; case STATE_FINISHED: if (ev.pulse) break; /* RC5-sz */ command = (data->bits & 0x0003F) >> 0; system = (data->bits & 0x02FC0) >> 6; toggle = (data->bits & 0x01000) ? 1 : 0; scancode = system << 6 | command; IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n", scancode, toggle); rc_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
static int af9015_rc_query(struct dvb_usb_device *d) { struct af9015_state *priv = d->priv; int ret; u8 buf[17]; /* read registers needed to detect remote controller code */ ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); if (ret) goto error; /* If any of these are non-zero, assume invalid data */ if (buf[1] || buf[2] || buf[3]) return ret; /* Check for repeat of previous code */ if ((priv->rc_repeat != buf[6] || buf[0]) && !memcmp(&buf[12], priv->rc_last, 4)) { deb_rc("%s: key repeated\n", __func__); rc_keydown(d->rc_dev, priv->rc_keycode, 0); priv->rc_repeat = buf[6]; return ret; } /* Only process key if canary killed */ if (buf[16] != 0xff && buf[0] != 0x01) { deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, buf[12], buf[13], buf[14], buf[15]); /* Reset the canary */ ret = af9015_write_reg(d, 0x98e9, 0xff); if (ret) goto error; /* Remember this key */ memcpy(priv->rc_last, &buf[12], 4); if (buf[14] == (u8) ~buf[15]) { if (buf[12] == (u8) ~buf[13]) { /* NEC */ priv->rc_keycode = buf[12] << 8 | buf[14]; } else { /* NEC extended*/ priv->rc_keycode = buf[12] << 16 | buf[13] << 8 | buf[14]; } } else { /* 32 bit NEC */ priv->rc_keycode = buf[12] << 24 | buf[13] << 16 | buf[14] << 8 | buf[15]; } rc_keydown(d->rc_dev, priv->rc_keycode, 0); } else { deb_rc("%s: no key press\n", __func__); /* Invalidate last keypress */ /* Not really needed, but helps with debug */ priv->rc_last[2] = priv->rc_last[3]; } priv->rc_repeat = buf[6]; error: if (ret) err("%s: failed:%d", __func__, ret); return ret; }
static void lme2510_int_response(struct urb *lme_urb) { struct dvb_usb_adapter *adap = lme_urb->context; struct lme2510_state *st = adap_to_priv(adap); static u8 *ibuf, *rbuf; int i = 0, offset; u32 key; switch (lme_urb->status) { case 0: case -ETIMEDOUT: break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: return; default: info("Error %x", lme_urb->status); break; } rbuf = (u8 *) lme_urb->transfer_buffer; offset = ((lme_urb->actual_length/8) > 4) ? 4 : (lme_urb->actual_length/8) ; for (i = 0; i < offset; ++i) { ibuf = (u8 *)&rbuf[i*8]; deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x", offset, i, ibuf[0], ibuf[1]); switch (ibuf[0]) { case 0xaa: debug_data_snipet(1, "INT Remote data snipet", ibuf); if ((ibuf[4] + ibuf[5]) == 0xff) { key = RC_SCANCODE_NECX((ibuf[2] ^ 0xff) << 8 | (ibuf[3] > 0) ? (ibuf[3] ^ 0xff) : 0, ibuf[5]); deb_info(1, "INT Key =%08x", key); if (adap_to_d(adap)->rc_dev != NULL) rc_keydown(adap_to_d(adap)->rc_dev, RC_TYPE_NEC, key, 0); } break; case 0xbb: switch (st->tuner_config) { case TUNER_LG: if (ibuf[2] > 0) st->signal_lock = ibuf[2]; st->signal_level = ibuf[4]; st->signal_sn = ibuf[3]; st->time_key = ibuf[7]; break; case TUNER_S7395: case TUNER_S0194: /* Tweak for earlier firmware*/ if (ibuf[1] == 0x03) { if (ibuf[2] > 1) st->signal_lock = ibuf[2]; st->signal_level = ibuf[3]; st->signal_sn = ibuf[4]; } else { st->signal_level = ibuf[4]; st->signal_sn = ibuf[5]; st->signal_lock = (st->signal_lock & 0xf7) + ((ibuf[2] & 0x01) << 0x03); } break; case TUNER_RS2000: if (ibuf[2] & 0x1) st->signal_lock = 0xff; else st->signal_lock = 0x00; st->signal_level = ibuf[5]; st->signal_sn = ibuf[4]; st->time_key = ibuf[7]; default: break; } debug_data_snipet(5, "INT Remote data snipet in", ibuf); break; case 0xcc: debug_data_snipet(1, "INT Control data snipet", ibuf); break; default: debug_data_snipet(1, "INT Unknown data snipet", ibuf); break; } } usb_submit_urb(lme_urb, GFP_ATOMIC); /* interrupt urb is due every 48 msecs while streaming * add 12msecs for system lag */ st->int_urb_due = jiffies + msecs_to_jiffies(60); }
/** * ir_xmp_decode() - Decode one XMP pulse or space * @dev: the struct rc_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct xmp_dec *data = &dev->raw->xmp; if (!(dev->enabled_protocols & RC_BIT_XMP)) return 0; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } IR_dprintk(2, "XMP decode started at state %d %d (%uus %s)\n", data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (eq_margin(ev.duration, XMP_LEADER, XMP_UNIT / 2)) { data->count = 0; data->state = STATE_NIBBLE_SPACE; } return 0; case STATE_LEADER_PULSE: if (!ev.pulse) break; if (eq_margin(ev.duration, XMP_LEADER, XMP_UNIT / 2)) data->state = STATE_NIBBLE_SPACE; return 0; case STATE_NIBBLE_SPACE: if (ev.pulse) break; if (geq_margin(ev.duration, XMP_TRAILER_SPACE, XMP_NIBBLE_PREFIX)) { int divider, i; u8 addr, subaddr, subaddr2, toggle, oem, obc1, obc2, sum1, sum2; u32 *n; u32 scancode; if (data->count != 16) { IR_dprintk(2, "received TRAILER period at index %d: %u\n", data->count, ev.duration); data->state = STATE_INACTIVE; return -EINVAL; } n = data->durations; /* * the 4th nibble should be 15 so base the divider on this * to transform durations into nibbles. Substract 2000 from * the divider to compensate for fluctuations in the signal */ divider = (n[3] - XMP_NIBBLE_PREFIX) / 15 - 2000; if (divider < 50) { IR_dprintk(2, "divider to small %d.\n", divider); data->state = STATE_INACTIVE; return -EINVAL; } /* convert to nibbles and do some sanity checks */ for (i = 0; i < 16; i++) n[i] = (n[i] - XMP_NIBBLE_PREFIX) / divider; sum1 = (15 + n[0] + n[1] + n[2] + n[3] + n[4] + n[5] + n[6] + n[7]) % 16; sum2 = (15 + n[8] + n[9] + n[10] + n[11] + n[12] + n[13] + n[14] + n[15]) % 16; if (sum1 != 15 || sum2 != 15) { IR_dprintk(2, "checksum errors sum1=0x%X sum2=0x%X\n", sum1, sum2); data->state = STATE_INACTIVE; return -EINVAL; } subaddr = n[0] << 4 | n[2]; subaddr2 = n[8] << 4 | n[11]; oem = n[4] << 4 | n[5]; addr = n[6] << 4 | n[7]; toggle = n[10]; obc1 = n[12] << 4 | n[13]; obc2 = n[14] << 4 | n[15]; if (subaddr != subaddr2) { IR_dprintk(2, "subaddress nibbles mismatch 0x%02X != 0x%02X\n", subaddr, subaddr2); data->state = STATE_INACTIVE; return -EINVAL; } if (oem != 0x44) IR_dprintk(1, "Warning: OEM nibbles 0x%02X. Expected 0x44\n", oem); scancode = addr << 24 | subaddr << 16 | obc1 << 8 | obc2; IR_dprintk(1, "XMP scancode 0x%06x\n", scancode); if (toggle == 0) { rc_keydown(dev, RC_TYPE_XMP, scancode, 0); } else { rc_repeat(dev); IR_dprintk(1, "Repeat last key\n"); } data->state = STATE_INACTIVE; return 0; } else if (geq_margin(ev.duration, XMP_HALFFRAME_SPACE, XMP_NIBBLE_PREFIX)) { /* Expect 8 or 16 nibble pulses. 16 in case of 'final' frame */ if (data->count == 16) { IR_dprintk(2, "received half frame pulse at index %d. Probably a final frame key-up event: %u\n", data->count, ev.duration); /* * TODO: for now go back to half frame position * so trailer can be found and key press * can be handled. */ data->count = 8; } else if (data->count != 8) IR_dprintk(2, "received half frame pulse at index %d: %u\n", data->count, ev.duration); data->state = STATE_LEADER_PULSE; return 0; } else if (geq_margin(ev.duration, XMP_NIBBLE_PREFIX, XMP_UNIT)) { /* store nibble raw data, decode after trailer */ if (data->count == 16) { IR_dprintk(2, "to many pulses (%d) ignoring: %u\n", data->count, ev.duration); data->state = STATE_INACTIVE; return -EINVAL; } data->durations[data->count] = ev.duration; data->count++; data->state = STATE_LEADER_PULSE; return 0; } break; } IR_dprintk(1, "XMP decode failed at count %d state %d (%uus %s)\n", data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
static void lme2510_int_response(struct urb *lme_urb) { struct dvb_usb_adapter *adap = lme_urb->context; struct lme2510_state *st = adap->dev->priv; static u8 *ibuf, *rbuf; int i = 0, offset; u32 key; switch (lme_urb->status) { case 0: case -ETIMEDOUT: break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: return; default: info("Error %x", lme_urb->status); break; } rbuf = (u8 *) lme_urb->transfer_buffer; offset = ((lme_urb->actual_length/8) > 4) ? 4 : (lme_urb->actual_length/8) ; for (i = 0; i < offset; ++i) { ibuf = (u8 *)&rbuf[i*8]; deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x", offset, i, ibuf[0], ibuf[1]); switch (ibuf[0]) { case 0xaa: debug_data_snipet(1, "INT Remote data snipet", ibuf); if ((ibuf[4] + ibuf[5]) == 0xff) { key = ibuf[5]; key += (ibuf[3] > 0) ? (ibuf[3] ^ 0xff) << 8 : 0; key += (ibuf[2] ^ 0xff) << 16; deb_info(1, "INT Key =%08x", key); if (adap->dev->rc_dev != NULL) rc_keydown(adap->dev->rc_dev, key, 0); } break; case 0xbb: switch (st->tuner_config) { case TUNER_LG: if (ibuf[2] > 0) st->signal_lock = ibuf[2]; st->signal_level = ibuf[4]; st->signal_sn = ibuf[3]; st->time_key = ibuf[7]; break; case TUNER_S7395: case TUNER_S0194: if (ibuf[1] == 0x03) { if (ibuf[2] > 1) st->signal_lock = ibuf[2]; st->signal_level = ibuf[3]; st->signal_sn = ibuf[4]; } else { st->signal_level = ibuf[4]; st->signal_sn = ibuf[5]; st->signal_lock = (st->signal_lock & 0xf7) + ((ibuf[2] & 0x01) << 0x03); } break; case TUNER_RS2000: if (ibuf[2] > 0) st->signal_lock = 0xff; else st->signal_lock = 0xf0; st->signal_level = ibuf[4]; st->signal_sn = ibuf[5]; st->time_key = ibuf[7]; default: break; } debug_data_snipet(5, "INT Remote data snipet in", ibuf); break; case 0xcc: debug_data_snipet(1, "INT Control data snipet", ibuf); break; default: debug_data_snipet(1, "INT Unknown data snipet", ibuf); break; } } usb_submit_urb(lme_urb, GFP_ATOMIC); }
/** * ir_rc6_decode() - Decode one RC6 pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc6_dec *data = &dev->raw->rc6; u32 scancode; u8 toggle; if (!(dev->raw->enabled_protocols & RC_TYPE_RC6)) return 0; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) goto out; again: IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; /* Note: larger margin on first pulse since each RC6_UNIT is quite short and some hardware takes some time to adjust to the signal */ if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT)) break; data->state = STATE_PREFIX_SPACE; data->count = 0; return 0; case STATE_PREFIX_SPACE: if (ev.pulse) break; if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2)) break; data->state = STATE_HEADER_BIT_START; return 0; case STATE_HEADER_BIT_START: if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) break; data->header <<= 1; if (ev.pulse) data->header |= 1; data->count++; data->state = STATE_HEADER_BIT_END; return 0; case STATE_HEADER_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == RC6_HEADER_NBITS) data->state = STATE_TOGGLE_START; else data->state = STATE_HEADER_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_TOGGLE_START: if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2)) break; data->toggle = ev.pulse; data->state = STATE_TOGGLE_END; return 0; case STATE_TOGGLE_END: if (!is_transition(&ev, &dev->raw->prev_ev) || !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) break; if (!(data->header & RC6_STARTBIT_MASK)) { IR_dprintk(1, "RC6 invalid start bit\n"); break; } data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_TOGGLE_END); data->count = 0; switch (rc6_mode(data)) { case RC6_MODE_0: data->wanted_bits = RC6_0_NBITS; break; case RC6_MODE_6A: /* This might look weird, but we basically check the value of the first body bit to determine the number of bits in mode 6A */ if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) || geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) data->wanted_bits = RC6_6A_LARGE_NBITS; else data->wanted_bits = RC6_6A_SMALL_NBITS; break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } goto again; case STATE_BODY_BIT_START: if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) break; data->body <<= 1; if (ev.pulse) data->body |= 1; data->count++; data->state = STATE_BODY_BIT_END; return 0; case STATE_BODY_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_FINISHED: if (ev.pulse) break; switch (rc6_mode(data)) { case RC6_MODE_0: scancode = data->body & 0xffff; toggle = data->toggle; IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", scancode, toggle); break; case RC6_MODE_6A: if (data->wanted_bits == RC6_6A_LARGE_NBITS) { toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0; scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK; } else { toggle = 0; scancode = data->body & 0xffffff; } IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n", scancode, toggle); break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } rc_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
static int af9015_rc_query(struct dvb_usb_device *d) { struct af9015_state *state = d_to_priv(d); int ret; u8 buf[17]; /* read registers needed to detect remote controller code */ ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); if (ret) goto error; /* If any of these are non-zero, assume invalid data */ if (buf[1] || buf[2] || buf[3]) { dev_dbg(&d->udev->dev, "%s: invalid data\n", __func__); return ret; } /* Check for repeat of previous code */ if ((state->rc_repeat != buf[6] || buf[0]) && !memcmp(&buf[12], state->rc_last, 4)) { dev_dbg(&d->udev->dev, "%s: key repeated\n", __func__); rc_repeat(d->rc_dev); state->rc_repeat = buf[6]; return ret; } /* Only process key if canary killed */ if (buf[16] != 0xff && buf[0] != 0x01) { dev_dbg(&d->udev->dev, "%s: key pressed %*ph\n", __func__, 4, buf + 12); /* Reset the canary */ ret = af9015_write_reg(d, 0x98e9, 0xff); if (ret) goto error; /* Remember this key */ memcpy(state->rc_last, &buf[12], 4); if (buf[14] == (u8) ~buf[15]) { if (buf[12] == (u8) ~buf[13]) { /* NEC */ state->rc_keycode = RC_SCANCODE_NEC(buf[12], buf[14]); } else { /* NEC extended*/ state->rc_keycode = RC_SCANCODE_NECX(buf[12] << 8 | buf[13], buf[14]); } } else { /* 32 bit NEC */ state->rc_keycode = RC_SCANCODE_NEC32(buf[12] << 24 | buf[13] << 16 | buf[14] << 8 | buf[15]); } rc_keydown(d->rc_dev, RC_TYPE_NEC, state->rc_keycode, 0); } else { dev_dbg(&d->udev->dev, "%s: no key press\n", __func__); /* Invalidate last keypress */ /* Not really needed, but helps with debug */ state->rc_last[2] = state->rc_last[3]; } state->rc_repeat = buf[6]; state->rc_failed = false; error: if (ret) { dev_warn(&d->udev->dev, "%s: rc query failed=%d\n", KBUILD_MODNAME, ret); /* allow random errors as dvb-usb will stop polling on error */ if (!state->rc_failed) ret = 0; state->rc_failed = true; } return ret; }
/** * ir_nec_decode() - Decode one NEC pulse or space * @dev: the struct rc_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct nec_dec *data = &dev->raw->nec; u32 scancode; u8 address, not_address, command, not_command; bool send_32bits = false; if (!(dev->raw->enabled_protocols & RC_TYPE_NEC)) return 0; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2)) { data->is_nec_x = false; data->necx_repeat = false; } else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2)) data->is_nec_x = true; else break; data->count = 0; data->state = STATE_HEADER_SPACE; return 0; case STATE_HEADER_SPACE: if (ev.pulse) break; if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { if (!dev->keypressed) { IR_dprintk(1, "Discarding last key repeat: event after key up\n"); } else { rc_repeat(dev); IR_dprintk(1, "Repeat last key\n"); data->state = STATE_TRAILER_PULSE; } return 0; } break; case STATE_BIT_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2)) break; data->state = STATE_BIT_SPACE; return 0; case STATE_BIT_SPACE: if (ev.pulse) break; if (data->necx_repeat && data->count == NECX_REPEAT_BITS && geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) { IR_dprintk(1, "Repeat last key\n"); rc_repeat(dev); data->state = STATE_INACTIVE; return 0; } else if (data->count > NECX_REPEAT_BITS) data->necx_repeat = false; data->bits <<= 1; if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) data->bits |= 1; else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2)) break; data->count++; if (data->count == NEC_NBITS) data->state = STATE_TRAILER_PULSE; else data->state = STATE_BIT_PULSE; return 0; case STATE_TRAILER_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2)) break; data->state = STATE_TRAILER_SPACE; return 0; case STATE_TRAILER_SPACE: if (ev.pulse) break; if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) break; address = bitrev8((data->bits >> 24) & 0xff); not_address = bitrev8((data->bits >> 16) & 0xff); command = bitrev8((data->bits >> 8) & 0xff); not_command = bitrev8((data->bits >> 0) & 0xff); if ((command ^ not_command) != 0xff) { IR_dprintk(1, "NEC checksum error: received 0x%08x\n", data->bits); send_32bits = true; } if (send_32bits) { /* NEC transport, but modified protocol, used by at * least Apple and TiVo remotes */ scancode = data->bits; IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode); } else if ((address ^ not_address) != 0xff) { /* Extended NEC */ scancode = address << 16 | not_address << 8 | command; IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); } else { /* Normal NEC */ scancode = address << 8 | command; IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); } if (data->is_nec_x) data->necx_repeat = true; rc_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc6_dec *data = &dev->raw->rc6; u32 scancode; u8 toggle; if (!(dev->raw->enabled_protocols & RC_TYPE_RC6)) return 0; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) goto out; again: IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT)) break; data->state = STATE_PREFIX_SPACE; data->count = 0; return 0; case STATE_PREFIX_SPACE: if (ev.pulse) break; if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2)) break; data->state = STATE_HEADER_BIT_START; data->header = 0; return 0; case STATE_HEADER_BIT_START: if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) break; data->header <<= 1; if (ev.pulse) data->header |= 1; data->count++; data->state = STATE_HEADER_BIT_END; return 0; case STATE_HEADER_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == RC6_HEADER_NBITS) data->state = STATE_TOGGLE_START; else data->state = STATE_HEADER_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_TOGGLE_START: if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2)) break; data->toggle = ev.pulse; data->state = STATE_TOGGLE_END; return 0; case STATE_TOGGLE_END: if (!is_transition(&ev, &dev->raw->prev_ev) || !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) break; if (!(data->header & RC6_STARTBIT_MASK)) { IR_dprintk(1, "RC6 invalid start bit\n"); break; } data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_TOGGLE_END); data->count = 0; data->body = 0; switch (rc6_mode(data)) { case RC6_MODE_0: data->wanted_bits = RC6_0_NBITS; break; case RC6_MODE_6A: data->wanted_bits = RC6_6A_NBITS; break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } goto again; case STATE_BODY_BIT_START: if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) { if (data->count++ < CHAR_BIT * sizeof data->body) { data->body <<= 1; if (ev.pulse) data->body |= 1; } data->state = STATE_BODY_BIT_END; return 0; } else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse && geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) { data->state = STATE_FINISHED; goto again; } break; case STATE_BODY_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_FINISHED: if (ev.pulse) break; switch (rc6_mode(data)) { case RC6_MODE_0: scancode = data->body; toggle = data->toggle; IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", scancode, toggle); break; case RC6_MODE_6A: if (data->count > CHAR_BIT * sizeof data->body) { IR_dprintk(1, "RC6 too many (%u) data bits\n", data->count); goto out; } scancode = data->body; if (data->count == RC6_6A_32_NBITS && (scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0; scancode &= ~RC6_6A_MCE_TOGGLE_MASK; } else { toggle = 0; } IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n", scancode, toggle); break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } rc_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_sony_decode() - Decode one Sony pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct sony_dec *data = &dev->raw->sony; u32 scancode; u8 device, subdevice, function; if (!(dev->raw->enabled_protocols & RC_TYPE_SONY)) return 0; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) goto out; IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2)) break; data->count = 0; data->state = STATE_HEADER_SPACE; return 0; case STATE_HEADER_SPACE: if (ev.pulse) break; if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2)) break; data->state = STATE_BIT_PULSE; return 0; case STATE_BIT_PULSE: if (!ev.pulse) break; data->bits <<= 1; if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2)) data->bits |= 1; else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2)) break; data->count++; data->state = STATE_BIT_SPACE; return 0; case STATE_BIT_SPACE: if (ev.pulse) break; if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2)) break; decrease_duration(&ev, SONY_BIT_SPACE); if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; } data->state = STATE_FINISHED; /* Fall through */ case STATE_FINISHED: if (ev.pulse) break; if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2)) break; switch (data->count) { case 12: device = bitrev8((data->bits << 3) & 0xF8); subdevice = 0; function = bitrev8((data->bits >> 4) & 0xFE); break; case 15: device = bitrev8((data->bits >> 0) & 0xFF); subdevice = 0; function = bitrev8((data->bits >> 7) & 0xFD); break; case 20: device = bitrev8((data->bits >> 5) & 0xF8); subdevice = bitrev8((data->bits >> 0) & 0xFF); function = bitrev8((data->bits >> 12) & 0xFE); break; default: IR_dprintk(1, "Sony invalid bitcount %u\n", data->count); goto out; } scancode = device << 16 | subdevice << 8 | function; IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); rc_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "Sony decode failed at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
static void lme2510_int_response(struct urb *lme_urb) { struct dvb_usb_adapter *adap = lme_urb->context; struct lme2510_state *st = adap_to_priv(adap); u8 *ibuf, *rbuf; int i = 0, offset; u32 key; u8 signal_lock = 0; switch (lme_urb->status) { case 0: case -ETIMEDOUT: break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: return; default: info("Error %x", lme_urb->status); break; } rbuf = (u8 *) lme_urb->transfer_buffer; offset = ((lme_urb->actual_length/8) > 4) ? 4 : (lme_urb->actual_length/8) ; for (i = 0; i < offset; ++i) { ibuf = (u8 *)&rbuf[i*8]; deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x", offset, i, ibuf[0], ibuf[1]); switch (ibuf[0]) { case 0xaa: debug_data_snipet(1, "INT Remote data snipet", ibuf); if (!adap_to_d(adap)->rc_dev) break; key = RC_SCANCODE_NEC32(ibuf[2] << 24 | ibuf[3] << 16 | ibuf[4] << 8 | ibuf[5]); deb_info(1, "INT Key = 0x%08x", key); rc_keydown(adap_to_d(adap)->rc_dev, RC_TYPE_NEC32, key, 0); break; case 0xbb: switch (st->tuner_config) { case TUNER_LG: signal_lock = ibuf[2] & BIT(5); st->signal_level = ibuf[4]; st->signal_sn = ibuf[3]; st->time_key = ibuf[7]; break; case TUNER_S7395: case TUNER_S0194: /* Tweak for earlier firmware*/ if (ibuf[1] == 0x03) { signal_lock = ibuf[2] & BIT(4); st->signal_level = ibuf[3]; st->signal_sn = ibuf[4]; } else { st->signal_level = ibuf[4]; st->signal_sn = ibuf[5]; } break; case TUNER_RS2000: signal_lock = ibuf[2] & 0xee; st->signal_level = ibuf[5]; st->signal_sn = ibuf[4]; st->time_key = ibuf[7]; default: break; } /* Interrupt will also throw just BIT 0 as lock */ signal_lock |= ibuf[2] & BIT(0); if (!signal_lock) st->lock_status &= ~FE_HAS_LOCK; lme2510_update_stats(adap); debug_data_snipet(5, "INT Remote data snipet in", ibuf); break; case 0xcc: debug_data_snipet(1, "INT Control data snipet", ibuf); break; default: debug_data_snipet(1, "INT Unknown data snipet", ibuf); break; } } usb_submit_urb(lme_urb, GFP_ATOMIC); /* Interrupt urb is due every 48 msecs while streaming the buffer * stores up to 4 periods if missed. Allow 200 msec for next interrupt. */ st->int_urb_due = jiffies + msecs_to_jiffies(200); }