Beispiel #1
0
/* process ir data stored in driver buffer */
static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
{
	DEFINE_IR_RAW_EVENT(rawir);
	u8 sample;
	bool event = false;
	int i;

	for (i = 0; i < fintek->pkts; i++) {
		sample = fintek->buf[i];
		switch (fintek->parser_state) {
		case CMD_HEADER:
			fintek->cmd = sample;
			if ((fintek->cmd == BUF_COMMAND_HEADER) ||
			    ((fintek->cmd & BUF_COMMAND_MASK) !=
			     BUF_PULSE_BIT)) {
				fintek->parser_state = SUBCMD;
				continue;
			}
			fintek->rem = (fintek->cmd & BUF_LEN_MASK);
			fit_dbg("%s: rem: 0x%02x", __func__, fintek->rem);
			if (fintek->rem)
				fintek->parser_state = PARSE_IRDATA;
			else
				ir_raw_event_reset(fintek->rdev);
			break;
		case SUBCMD:
			fintek->rem = fintek_cmdsize(fintek->cmd, sample);
			fintek->parser_state = CMD_DATA;
			break;
		case CMD_DATA:
			fintek->rem--;
			break;
		case PARSE_IRDATA:
			fintek->rem--;
			init_ir_raw_event(&rawir);
			rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
			rawir.duration = US_TO_NS((sample & BUF_SAMPLE_MASK)
					  * CIR_SAMPLE_PERIOD);

			fit_dbg("Storing %s with duration %d",
				rawir.pulse ? "pulse" : "space",
				rawir.duration);
			if (ir_raw_event_store_with_filter(fintek->rdev,
									&rawir))
				event = true;
			break;
		}

		if ((fintek->parser_state != CMD_HEADER) && !fintek->rem)
			fintek->parser_state = CMD_HEADER;
	}

	fintek->pkts = 0;

	if (event) {
		fit_dbg("Calling ir_raw_event_handle");
		ir_raw_event_handle(fintek->rdev);
	}
}
/* Receiver */
static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
			      ssize_t *num)
{
	struct cx25840_ir_state *ir_state = to_ir_state(sd);
	bool invert;
	u16 divider;
	unsigned int i, n;
	union cx25840_ir_fifo_rec *p;
	unsigned u, v, w;

	if (ir_state == NULL)
		return -ENODEV;

	invert = (bool) atomic_read(&ir_state->rx_invert);
	divider = (u16) atomic_read(&ir_state->rxclk_divider);

	n = count / sizeof(union cx25840_ir_fifo_rec)
		* sizeof(union cx25840_ir_fifo_rec);
	if (n == 0) {
		*num = 0;
		return 0;
	}

	n = kfifo_out_locked(&ir_state->rx_kfifo, buf, n,
			     &ir_state->rx_kfifo_lock);

	n /= sizeof(union cx25840_ir_fifo_rec);
	*num = n * sizeof(union cx25840_ir_fifo_rec);

	for (p = (union cx25840_ir_fifo_rec *) buf, i = 0; i < n; p++, i++) {

		if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
			/* Assume RTO was because of no IR light input */
			u = 0;
			w = 1;
		} else {
			u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0;
			if (invert)
				u = u ? 0 : 1;
			w = 0;
		}

		v = (unsigned) pulse_width_count_to_ns(
				  (u16) (p->hw_fifo_data & FIFO_RXTX), divider);
		if (v > IR_MAX_DURATION)
			v = IR_MAX_DURATION;

		init_ir_raw_event(&p->ir_core_data);
		p->ir_core_data.pulse = u;
		p->ir_core_data.duration = v;
		p->ir_core_data.timeout = w;

		v4l2_dbg(2, ir_debug, sd, "rx read: %10u ns  %s  %s\n",
			 v, u ? "mark" : "space", w ? "(timed out)" : "");
		if (w)
			v4l2_dbg(2, ir_debug, sd, "rx read: end of rx\n");
	}
	return 0;
}
Beispiel #3
0
/**
 * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not
 * @dev:	the struct rc_dev device descriptor
 * @idle:	whether the device is idle or not
 */
void ir_raw_event_set_idle(struct rc_dev *dev, bool idle)
{
	if (!dev->raw)
		return;

	IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");

	if (idle) {
		dev->raw->this_ev.timeout = true;
		ir_raw_event_store(dev, &dev->raw->this_ev);
		init_ir_raw_event(&dev->raw->this_ev);
	}

	if (dev->s_idle)
		dev->s_idle(dev, idle);

	dev->idle = idle;
}
static void process_ir_data(struct iguanair *ir, unsigned len)
{
	if (len >= 4 && ir->buf_in[0] == 0 && ir->buf_in[1] == 0) {
		switch (ir->buf_in[3]) {
		case CMD_TX_OVERFLOW:
			ir->tx_overflow = true;
		case CMD_RECEIVER_OFF:
		case CMD_RECEIVER_ON:
		case CMD_SEND:
			complete(&ir->completion);
			break;
		case CMD_RX_OVERFLOW:
			dev_warn(ir->dev, "receive overflow\n");
			break;
		default:
			dev_warn(ir->dev, "control code %02x received\n",
							ir->buf_in[3]);
			break;
		}
	} else if (len >= 7) {
		DEFINE_IR_RAW_EVENT(rawir);
		unsigned i;

		init_ir_raw_event(&rawir);

		for (i = 0; i < 7; i++) {
			if (ir->buf_in[i] == 0x80) {
				rawir.pulse = false;
				rawir.duration = US_TO_NS(21845);
			} else {
				rawir.pulse = (ir->buf_in[i] & 0x80) == 0;
				rawir.duration = ((ir->buf_in[i] & 0x7f) + 1) *
									 21330;
			}

			ir_raw_event_store_with_filter(ir->rc, &rawir);
		}

		ir_raw_event_handle(ir->rc);
	}
}
int picolcd_raw_cir(struct picolcd_data *data,
		struct hid_report *report, u8 *raw_data, int size)
{
	unsigned long flags;
	int i, w, sz;
	DEFINE_IR_RAW_EVENT(rawir);

	/* ignore if rc_dev is NULL or status is shunned */
	spin_lock_irqsave(&data->lock, flags);
	if (!data->rc_dev || (data->status & PICOLCD_CIR_SHUN)) {
		spin_unlock_irqrestore(&data->lock, flags);
		return 1;
	}
	spin_unlock_irqrestore(&data->lock, flags);

	/* PicoLCD USB packets contain 16-bit intervals in network order,
	 * with value negated for pulse. Intervals are in microseconds.
	 *
	 * Note: some userspace LIRC code for PicoLCD says negated values
	 * for space - is it a matter of IR chip? (pulse for my TSOP2236)
	 *
	 * In addition, the first interval seems to be around 15000 + base
	 * interval for non-first report of IR data - thus the quirk below
	 * to get RC_CODE to understand Sony and JVC remotes I have at hand
	 */
	sz = size > 0 ? min((int)raw_data[0], size-1) : 0;
	for (i = 0; i+1 < sz; i += 2) {
		init_ir_raw_event(&rawir);
		w = (raw_data[i] << 8) | (raw_data[i+1]);
		rawir.pulse = !!(w & 0x8000);
		rawir.duration = US_TO_NS(rawir.pulse ? (65536 - w) : w);
		/* Quirk!! - see above */
		if (i == 0 && rawir.duration > 15000000)
			rawir.duration -= 15000000;
		ir_raw_event_store(data->rc_dev, &rawir);
	}
	ir_raw_event_handle(data->rc_dev);

	return 1;
}
Beispiel #6
0
/**
 * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not
 * @dev:	the struct rc_dev device descriptor
 * @idle:	whether the device is idle or not
 */
void ir_raw_event_set_idle(struct rc_dev *dev, bool idle)
{
	if (!dev->raw)
		return;

#ifdef CONFIG_DEBUG_PRINTK
	IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
#else
	IR_d;
#endif

	if (idle) {
		dev->raw->this_ev.timeout = true;
		ir_raw_event_store(dev, &dev->raw->this_ev);
		init_ir_raw_event(&dev->raw->this_ev);
	}

	if (dev->s_idle)
		dev->s_idle(dev, idle);

	dev->idle = idle;
}
Beispiel #7
0
/* allocate memory, probe hardware, and initialize everything */
static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
		     *dev_id)
{
	const struct ite_dev_params *dev_desc = NULL;
	struct ite_dev *itdev = NULL;
	struct rc_dev *rdev = NULL;
	int ret = -ENOMEM;
	int model_no;
	int io_rsrc_no;

	ite_dbg("%s called", __func__);

	itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL);
	if (!itdev)
		return ret;

	/* input device for IR remote (and tx) */
	rdev = rc_allocate_device();
	if (!rdev)
		goto exit_free_dev_rdev;
	itdev->rdev = rdev;

	ret = -ENODEV;

	/* get the model number */
	model_no = (int)dev_id->driver_data;
	ite_pr(KERN_NOTICE, "Auto-detected model: %s\n",
		ite_dev_descs[model_no].model);

	if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) {
		model_no = model_number;
		ite_pr(KERN_NOTICE, "The model has been fixed by a module "
			"parameter.");
	}

	ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model);

	/* get the description for the device */
	dev_desc = &ite_dev_descs[model_no];
	io_rsrc_no = dev_desc->io_rsrc_no;

	/* validate pnp resources */
	if (!pnp_port_valid(pdev, io_rsrc_no) ||
	    pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) {
		dev_err(&pdev->dev, "IR PNP Port not valid!\n");
		goto exit_free_dev_rdev;
	}

	if (!pnp_irq_valid(pdev, 0)) {
		dev_err(&pdev->dev, "PNP IRQ not valid!\n");
		goto exit_free_dev_rdev;
	}

	/* store resource values */
	itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no);
	itdev->cir_irq = pnp_irq(pdev, 0);

	/* initialize spinlocks */
	spin_lock_init(&itdev->lock);

	/* initialize raw event */
	init_ir_raw_event(&itdev->rawir);

	/* set driver data into the pnp device */
	pnp_set_drvdata(pdev, itdev);
	itdev->pdev = pdev;

	/* initialize waitqueues for transmission */
	init_waitqueue_head(&itdev->tx_queue);
	init_waitqueue_head(&itdev->tx_ended);

	/* copy model-specific parameters */
	itdev->params = *dev_desc;

	/* apply any overrides */
	if (sample_period > 0)
		itdev->params.sample_period = sample_period;

	if (tx_carrier_freq > 0)
		itdev->params.tx_carrier_freq = tx_carrier_freq;

	if (tx_duty_cycle > 0 && tx_duty_cycle <= 100)
		itdev->params.tx_duty_cycle = tx_duty_cycle;

	if (rx_low_carrier_freq > 0)
		itdev->params.rx_low_carrier_freq = rx_low_carrier_freq;

	if (rx_high_carrier_freq > 0)
		itdev->params.rx_high_carrier_freq = rx_high_carrier_freq;

	/* print out parameters */
	ite_pr(KERN_NOTICE, "TX-capable: %d\n", (int)
			 itdev->params.hw_tx_capable);
	ite_pr(KERN_NOTICE, "Sample period (ns): %ld\n", (long)
		     itdev->params.sample_period);
	ite_pr(KERN_NOTICE, "TX carrier frequency (Hz): %d\n", (int)
		     itdev->params.tx_carrier_freq);
	ite_pr(KERN_NOTICE, "TX duty cycle (%%): %d\n", (int)
		     itdev->params.tx_duty_cycle);
	ite_pr(KERN_NOTICE, "RX low carrier frequency (Hz): %d\n", (int)
		     itdev->params.rx_low_carrier_freq);
	ite_pr(KERN_NOTICE, "RX high carrier frequency (Hz): %d\n", (int)
		     itdev->params.rx_high_carrier_freq);

	/* set up hardware initial state */
	itdev->params.init_hardware(itdev);

	/* set up ir-core props */
	rdev->priv = itdev;
	rdev->driver_type = RC_DRIVER_IR_RAW;
	rdev->allowed_protos = RC_BIT_ALL;
	rdev->open = ite_open;
	rdev->close = ite_close;
	rdev->s_idle = ite_s_idle;
	rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
	rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT;
	rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT;
	rdev->timeout = ITE_IDLE_TIMEOUT;
	rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
				itdev->params.sample_period;
	rdev->tx_resolution = ITE_BAUDRATE_DIVISOR *
				itdev->params.sample_period;

	/* set up transmitter related values if needed */
	if (itdev->params.hw_tx_capable) {
		rdev->tx_ir = ite_tx_ir;
		rdev->s_tx_carrier = ite_set_tx_carrier;
		rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle;
	}

	rdev->input_name = dev_desc->model;
	rdev->input_id.bustype = BUS_HOST;
	rdev->input_id.vendor = PCI_VENDOR_ID_ITE;
	rdev->input_id.product = 0;
	rdev->input_id.version = 0;
	rdev->driver_name = ITE_DRIVER_NAME;
	rdev->map_name = RC_MAP_RC6_MCE;

	ret = rc_register_device(rdev);
	if (ret)
		goto exit_free_dev_rdev;

	ret = -EBUSY;
	/* now claim resources */
	if (!request_region(itdev->cir_addr,
				dev_desc->io_region_size, ITE_DRIVER_NAME))
		goto exit_unregister_device;

	if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
			ITE_DRIVER_NAME, (void *)itdev))
		goto exit_release_cir_addr;

	ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");

	return 0;

exit_release_cir_addr:
	release_region(itdev->cir_addr, itdev->params.io_region_size);
exit_unregister_device:
	rc_unregister_device(rdev);
exit_free_dev_rdev:
	rc_free_device(rdev);
	kfree(itdev);

	return ret;
}
static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
		     *dev_id)
{
	const struct ite_dev_params *dev_desc = NULL;
	struct ite_dev *itdev = NULL;
	struct rc_dev *rdev = NULL;
	int ret = -ENOMEM;
	int model_no;
	int io_rsrc_no;

	ite_dbg("%s called", __func__);

	itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL);
	if (!itdev)
		return ret;

	
	rdev = rc_allocate_device();
	if (!rdev)
		goto failure;

	ret = -ENODEV;

	
	model_no = (int)dev_id->driver_data;
	ite_pr(KERN_NOTICE, "Auto-detected model: %s\n",
		ite_dev_descs[model_no].model);

	if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) {
		model_no = model_number;
		ite_pr(KERN_NOTICE, "The model has been fixed by a module "
			"parameter.");
	}

	ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model);

	
	dev_desc = &ite_dev_descs[model_no];
	io_rsrc_no = dev_desc->io_rsrc_no;

	
	if (!pnp_port_valid(pdev, io_rsrc_no) ||
	    pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) {
		dev_err(&pdev->dev, "IR PNP Port not valid!\n");
		goto failure;
	}

	if (!pnp_irq_valid(pdev, 0)) {
		dev_err(&pdev->dev, "PNP IRQ not valid!\n");
		goto failure;
	}

	
	itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no);
	itdev->cir_irq = pnp_irq(pdev, 0);

	
	spin_lock_init(&itdev->lock);

	
	init_ir_raw_event(&itdev->rawir);

	
	pnp_set_drvdata(pdev, itdev);
	itdev->pdev = pdev;

	
	init_waitqueue_head(&itdev->tx_queue);
	init_waitqueue_head(&itdev->tx_ended);

	
	itdev->params = *dev_desc;

	
	if (sample_period > 0)
		itdev->params.sample_period = sample_period;

	if (tx_carrier_freq > 0)
		itdev->params.tx_carrier_freq = tx_carrier_freq;

	if (tx_duty_cycle > 0 && tx_duty_cycle <= 100)
		itdev->params.tx_duty_cycle = tx_duty_cycle;

	if (rx_low_carrier_freq > 0)
		itdev->params.rx_low_carrier_freq = rx_low_carrier_freq;

	if (rx_high_carrier_freq > 0)
		itdev->params.rx_high_carrier_freq = rx_high_carrier_freq;

	
	ite_pr(KERN_NOTICE, "TX-capable: %d\n", (int)
			 itdev->params.hw_tx_capable);
	ite_pr(KERN_NOTICE, "Sample period (ns): %ld\n", (long)
		     itdev->params.sample_period);
	ite_pr(KERN_NOTICE, "TX carrier frequency (Hz): %d\n", (int)
		     itdev->params.tx_carrier_freq);
	ite_pr(KERN_NOTICE, "TX duty cycle (%%): %d\n", (int)
		     itdev->params.tx_duty_cycle);
	ite_pr(KERN_NOTICE, "RX low carrier frequency (Hz): %d\n", (int)
		     itdev->params.rx_low_carrier_freq);
	ite_pr(KERN_NOTICE, "RX high carrier frequency (Hz): %d\n", (int)
		     itdev->params.rx_high_carrier_freq);

	
	itdev->params.init_hardware(itdev);

	
	rdev->priv = itdev;
	rdev->driver_type = RC_DRIVER_IR_RAW;
	rdev->allowed_protos = RC_TYPE_ALL;
	rdev->open = ite_open;
	rdev->close = ite_close;
	rdev->s_idle = ite_s_idle;
	rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
	rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT;
	rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT;
	rdev->timeout = ITE_IDLE_TIMEOUT;
	rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
				itdev->params.sample_period;
	rdev->tx_resolution = ITE_BAUDRATE_DIVISOR *
				itdev->params.sample_period;

	
	if (itdev->params.hw_tx_capable) {
		rdev->tx_ir = ite_tx_ir;
		rdev->s_tx_carrier = ite_set_tx_carrier;
		rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle;
	}

	rdev->input_name = dev_desc->model;
	rdev->input_id.bustype = BUS_HOST;
	rdev->input_id.vendor = PCI_VENDOR_ID_ITE;
	rdev->input_id.product = 0;
	rdev->input_id.version = 0;
	rdev->driver_name = ITE_DRIVER_NAME;
	rdev->map_name = RC_MAP_RC6_MCE;

	ret = -EBUSY;
	
	if (!request_region(itdev->cir_addr,
				dev_desc->io_region_size, ITE_DRIVER_NAME))
		goto failure;

	if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
			ITE_DRIVER_NAME, (void *)itdev))
		goto failure;

	ret = rc_register_device(rdev);
	if (ret)
		goto failure;

	itdev->rdev = rdev;
	ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");

	return 0;

failure:
	if (itdev->cir_irq)
		free_irq(itdev->cir_irq, itdev);

	if (itdev->cir_addr)
		release_region(itdev->cir_addr, itdev->params.io_region_size);

	rc_free_device(rdev);
	kfree(itdev);

	return ret;
}
Beispiel #9
0
static int rtl2832u_rc_query(struct dvb_usb_device *d)
{
	int ret, i, len;
	struct rtl28xxu_priv *priv = d->priv;
	struct ir_raw_event ev;
	u8 buf[128];
	static const struct rtl28xxu_reg_val_mask refresh_tab[] = {
		{IR_RX_IF,               0x03, 0xff},
		{IR_RX_BUF_CTRL,         0x80, 0xff},
		{IR_RX_CTRL,             0x80, 0xff},
	};

	/* init remote controller */
	if (!priv->rc_active) {
		static const struct rtl28xxu_reg_val_mask init_tab[] = {
			{SYS_DEMOD_CTL1,         0x00, 0x04},
			{SYS_DEMOD_CTL1,         0x00, 0x08},
			{USB_CTRL,               0x20, 0x20},
			{SYS_GPIO_DIR,           0x00, 0x08},
			{SYS_GPIO_OUT_EN,        0x08, 0x08},
			{SYS_GPIO_OUT_VAL,       0x08, 0x08},
			{IR_MAX_DURATION0,       0xd0, 0xff},
			{IR_MAX_DURATION1,       0x07, 0xff},
			{IR_IDLE_LEN0,           0xc0, 0xff},
			{IR_IDLE_LEN1,           0x00, 0xff},
			{IR_GLITCH_LEN,          0x03, 0xff},
			{IR_RX_CLK,              0x09, 0xff},
			{IR_RX_CFG,              0x1c, 0xff},
			{IR_MAX_H_TOL_LEN,       0x1e, 0xff},
			{IR_MAX_L_TOL_LEN,       0x1e, 0xff},
			{IR_RX_CTRL,             0x80, 0xff},
		};

		for (i = 0; i < ARRAY_SIZE(init_tab); i++) {
			ret = rtl28xx_wr_reg_mask(d, init_tab[i].reg,
					init_tab[i].val, init_tab[i].mask);
			if (ret)
				goto err;
		}

		priv->rc_active = true;
	}

	ret = rtl28xx_rd_reg(d, IR_RX_IF, &buf[0]);
	if (ret)
		goto err;

	if (buf[0] != 0x83)
		goto exit;

	ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]);
	if (ret)
		goto err;

	len = buf[0];

	/* read raw code from hw */
	ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
	if (ret)
		goto err;

	/* let hw receive new code */
	for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) {
		ret = rtl28xx_wr_reg_mask(d, refresh_tab[i].reg,
				refresh_tab[i].val, refresh_tab[i].mask);
		if (ret)
			goto err;
	}

	/* pass data to Kernel IR decoder */
	init_ir_raw_event(&ev);

	for (i = 0; i < len; i++) {
		ev.pulse = buf[i] >> 7;
		ev.duration = 50800 * (buf[i] & 0x7f);
		ir_raw_event_store_with_filter(d->rc_dev, &ev);
	}

	/* 'flush' ir_raw_event_store_with_filter() */
	ir_raw_event_set_idle(d->rc_dev, true);
	ir_raw_event_handle(d->rc_dev);
exit:
	return ret;
err:
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
Beispiel #10
0
static void process_ir_data(struct iguanair *ir, unsigned len)
{
	if (len >= 4 && ir->buf_in[0] == 0 && ir->buf_in[1] == 0) {
		switch (ir->buf_in[3]) {
		case CMD_GET_VERSION:
			if (len == 6) {
				ir->version = (ir->buf_in[5] << 8) |
							ir->buf_in[4];
				complete(&ir->completion);
			}
			break;
		case CMD_GET_BUFSIZE:
			if (len >= 5) {
				ir->bufsize = ir->buf_in[4];
				complete(&ir->completion);
			}
			break;
		case CMD_GET_FEATURES:
			if (len > 5) {
				ir->cycle_overhead = ir->buf_in[5];
				complete(&ir->completion);
			}
			break;
		case CMD_TX_OVERFLOW:
			ir->tx_overflow = true;
		case CMD_RECEIVER_OFF:
		case CMD_RECEIVER_ON:
		case CMD_SEND:
			complete(&ir->completion);
			break;
		case CMD_RX_OVERFLOW:
			dev_warn(ir->dev, "receive overflow\n");
			ir_raw_event_reset(ir->rc);
			break;
		default:
			dev_warn(ir->dev, "control code %02x received\n",
							ir->buf_in[3]);
			break;
		}
	} else if (len >= 7) {
		DEFINE_IR_RAW_EVENT(rawir);
		unsigned i;
		bool event = false;

		init_ir_raw_event(&rawir);

		for (i = 0; i < 7; i++) {
			if (ir->buf_in[i] == 0x80) {
				rawir.pulse = false;
				rawir.duration = US_TO_NS(21845);
			} else {
				rawir.pulse = (ir->buf_in[i] & 0x80) == 0;
				rawir.duration = ((ir->buf_in[i] & 0x7f) + 1) *
								 RX_RESOLUTION;
			}

			if (ir_raw_event_store_with_filter(ir->rc, &rawir))
				event = true;
		}

		if (event)
			ir_raw_event_handle(ir->rc);
	}
}