/* 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; }
/** * 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; }
/** * 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; }
/* 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; }
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; }
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); } }