Пример #1
0
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;
	}
}
Пример #3
0
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 :-) */
}
Пример #4
0
/**
 * 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;
}