static void rbwrite(int l) { if (lirc_buffer_full(&rbuf)) { /* no new signals will be accepted */ dprintk("Buffer overrun\n"); return; } lirc_buffer_write(&rbuf, (void *)&l); }
static void send_fragment(struct igorplug *ir, struct lirc_buffer *buf, int i, int max) { int code; /* MODE2: pulse/space (PULSE_BIT) in 1us units */ while (i < max) { /* 1 Igor-tick = 85.333333 us */ code = (unsigned int)ir->buf_in[i] * 85 + (unsigned int)ir->buf_in[i] / 3; ir->last_time.tv_usec += code; if (ir->in_space) code |= PULSE_BIT; lirc_buffer_write(buf, (unsigned char *)&code); /* 1 chunk = CODE_LENGTH bytes */ ir->in_space ^= 1; ++i; } }
static void urb_complete(struct urb *urb) #endif { struct ttusbir_device *ttusbir; unsigned char *buf; int i; lirc_t l; ttusbir = urb->context; if (!ttusbir->opened) return; buf = (unsigned char *)urb->transfer_buffer; for (i = 0; i < 128; i++) { /* Here we do the filtering and some kind of down sampling */ buf[i] = ~map_table[buf[i]]; if (ttusbir->last_pulse == buf[i]) { if (ttusbir->last_num < PULSE_MASK/63) ttusbir->last_num++; /* * else we are in a idle period and do not need to * increment any longer */ } else { l = ttusbir->last_num * 62; /* about 62 = us/byte */ if (ttusbir->last_pulse) /* pulse or space? */ l |= PULSE_BIT; if (!lirc_buffer_full(&ttusbir->rbuf)) { lirc_buffer_write(&ttusbir->rbuf, (void *)&l); wake_up_interruptible(&ttusbir->rbuf.wait_poll); } ttusbir->last_num = 0; ttusbir->last_pulse = buf[i]; } } usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */ }
/** * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the * lircd userspace daemon for decoding. * @input_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 lirc interfaces aren't wired up. */ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct lirc_codec *lirc = &dev->raw->lirc; int sample; if (!(dev->raw->enabled_protocols & RC_BIT_LIRC)) return 0; if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) return -EINVAL; /* Packet start */ if (ev.reset) return 0; /* Carrier reports */ if (ev.carrier_report) { sample = LIRC_FREQUENCY(ev.carrier); IR_dprintk(2, "carrier report (freq: %d)\n", sample); /* Packet end */ } else if (ev.timeout) { if (lirc->gap) return 0; lirc->gap_start = ktime_get(); lirc->gap = true; lirc->gap_duration = ev.duration; if (!lirc->send_timeout_reports) return 0; sample = LIRC_TIMEOUT(ev.duration / 1000); IR_dprintk(2, "timeout report (duration: %d)\n", sample); /* Normal sample */ } else { if (lirc->gap) { int gap_sample; lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), lirc->gap_start)); /* Convert to ms and cap by LIRC_VALUE_MASK */ do_div(lirc->gap_duration, 1000); lirc->gap_duration = min(lirc->gap_duration, (u64)LIRC_VALUE_MASK); gap_sample = LIRC_SPACE(lirc->gap_duration); lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &gap_sample); lirc->gap = false; } sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : LIRC_SPACE(ev.duration / 1000); IR_dprintk(2, "delivering %uus %s to lirc_dev\n", TO_US(ev.duration), TO_STR(ev.pulse)); } lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &sample); wake_up(&dev->raw->lirc.drv->rbuf->wait_poll); return 0; }
/** * Called in user context. * return 0 if data was added to the buffer and * -ENODATA if none was available. This should add some number of bits * evenly divisible by code_length to the buffer */ static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf) { int ret; struct igorplug *ir = (struct igorplug *)data; if (!ir || !ir->usbdev) /* Has the device been removed? */ return -ENODEV; memset(ir->buf_in, 0, ir->len_in); ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), GET_INFRACODE, USB_TYPE_VENDOR | USB_DIR_IN, 0/* offset */, /*unused*/0, ir->buf_in, ir->len_in, /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); if (ret > 0) { int code, timediff; struct timeval now; /* ACK packet has 1 byte --> ignore */ if (ret < DEVICE_HEADERLEN) return -ENODATA; dprintk(DRIVER_NAME ": Got %d bytes. Header: %*ph\n", ret, 3, ir->buf_in); do_gettimeofday(&now); timediff = now.tv_sec - ir->last_time.tv_sec; if (timediff + 1 > PULSE_MASK / 1000000) timediff = PULSE_MASK; else { timediff *= 1000000; timediff += now.tv_usec - ir->last_time.tv_usec; } ir->last_time.tv_sec = now.tv_sec; ir->last_time.tv_usec = now.tv_usec; /* create leading gap */ code = timediff; lirc_buffer_write(buf, (unsigned char *)&code); ir->in_space = 1; /* next comes a pulse */ if (ir->buf_in[2] == 0) send_fragment(ir, buf, DEVICE_HEADERLEN, ret); else { dev_warn(&ir->usbdev->dev, "[%d]: Device buffer overrun.\n", ir->devnum); /* HHHNNNNNNNNNNNOOOOOOOO H = header <---[2]---> N = newer <---------ret--------> O = older */ ir->buf_in[2] %= ret - DEVICE_HEADERLEN; /* sanitize */ /* keep even-ness to not desync pulse/pause */ send_fragment(ir, buf, DEVICE_HEADERLEN + ir->buf_in[2] - (ir->buf_in[2] & 1), ret); send_fragment(ir, buf, DEVICE_HEADERLEN, DEVICE_HEADERLEN + ir->buf_in[2]); } ret = usb_control_msg( ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, /*unused*/0, /*unused*/0, /*dummy*/ir->buf_in, /*dummy*/ir->len_in, /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); if (ret < 0) printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: " "error %d\n", ir->devnum, ret); return 0; } else if (ret < 0) printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n", ir->devnum, ret); return -ENODATA; }