static void wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device) { u8 irdata; DEFINE_IR_RAW_EVENT(rawir); unsigned duration; /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) { irdata = inb(data->sbase + WBCIR_REG_SP3_RXDATA); if (data->rxstate == WBCIR_RXSTATE_ERROR) continue; duration = ((irdata & 0x7F) + 1) * (data->carrier_report_enabled ? 2 : 10); rawir.pulse = irdata & 0x80 ? false : true; rawir.duration = US_TO_NS(duration); if (rawir.pulse) data->pulse_duration += duration; ir_raw_event_store_with_filter(data->dev, &rawir); } ir_raw_event_handle(data->dev); }
/* must be called with priv->lock held */ static void img_ir_refresh_raw(struct img_ir_priv *priv, u32 irq_status) { struct img_ir_priv_raw *raw = &priv->raw; struct rc_dev *rc_dev = priv->raw.rdev; int multiple; u32 ir_status; /* find whether both rise and fall was detected */ multiple = ((irq_status & IMG_IR_IRQ_EDGE) == IMG_IR_IRQ_EDGE); /* * If so, we need to see if the level has actually changed. * If it's just noise that we didn't have time to process, * there's no point reporting it. */ ir_status = img_ir_read(priv, IMG_IR_STATUS) & IMG_IR_IRRXD; if (multiple && ir_status == raw->last_status) return; raw->last_status = ir_status; /* report the edge to the IR raw decoders */ if (ir_status) /* low */ ir_raw_event_store_edge(rc_dev, IR_SPACE); else /* high */ ir_raw_event_store_edge(rc_dev, IR_PULSE); ir_raw_event_handle(rc_dev); }
/* SECTION: Hardware */ static void sir_timeout(unsigned long data) { /* * if last received signal was a pulse, but receiving stopped * within the 9 bit frame, we need to finish this pulse and * simulate a signal change to from pulse to space. Otherwise * upper layers will receive two sequences next time. */ unsigned long flags; unsigned long pulse_end; /* avoid interference with interrupt */ spin_lock_irqsave(&timer_lock, flags); if (last_value) { /* clear unread bits in UART and restart */ outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); /* determine 'virtual' pulse end: */ pulse_end = min_t(unsigned long, ktime_us_delta(last, last_intr_time), IR_MAX_DURATION); dev_dbg(&sir_ir_dev->dev, "timeout add %d for %lu usec\n", last_value, pulse_end); add_read_queue(last_value, pulse_end); last_value = 0; last = last_intr_time; } spin_unlock_irqrestore(&timer_lock, flags); ir_raw_event_handle(rcdev); }
static int loop_set_wakeup_filter(struct rc_dev *dev, struct rc_scancode_filter *sc) { static const unsigned int max = 512; struct ir_raw_event *raw; int ret; int i; /* fine to disable filter */ if (!sc->mask) return 0; /* encode the specified filter and loop it back */ raw = kmalloc_array(max, sizeof(*raw), GFP_KERNEL); if (!raw) return -ENOMEM; ret = ir_raw_encode_scancode(dev->wakeup_protocol, sc->data, raw, max); /* still loop back the partial raw IR even if it's incomplete */ if (ret == -ENOBUFS) ret = max; if (ret >= 0) { /* do the loopback */ for (i = 0; i < ret; ++i) ir_raw_event_store(dev, &raw[i]); ir_raw_event_handle(dev); ret = 0; } kfree(raw); return ret; }
static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) { struct gpio_rc_dev *gpio_dev = dev_id; int gval; int rc = 0; enum raw_event_type type = IR_SPACE; gval = gpio_get_value_cansleep(gpio_dev->gpio_nr); if (gval < 0) goto err_get_value; if (gpio_dev->active_low) gval = !gval; if (gval == 1) type = IR_PULSE; rc = ir_raw_event_store_edge(gpio_dev->rcdev, type); if (rc < 0) goto err_get_value; ir_raw_event_handle(gpio_dev->rcdev); err_get_value: return IRQ_HANDLED; }
static void cx23885_input_process_measurements(struct cx23885_dev *dev, bool overrun) { struct cx23885_kernel_ir *kernel_ir = dev->kernel_ir; ssize_t num; int count, i; bool handle = false; struct ir_raw_event ir_core_event[64]; do { num = 0; v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ir_core_event, sizeof(ir_core_event), &num); count = num / sizeof(struct ir_raw_event); for (i = 0; i < count; i++) { ir_raw_event_store(kernel_ir->inp_dev, &ir_core_event[i]); handle = true; } } while (num != 0); if (overrun) ir_raw_event_reset(kernel_ir->inp_dev); else if (handle) ir_raw_event_handle(kernel_ir->inp_dev); }
static int loop_tx_ir(struct rc_dev *dev, int *txbuf, u32 n) { struct loopback_dev *lodev = dev->priv; u32 rxmask; unsigned count; unsigned total_duration = 0; unsigned i; DEFINE_IR_RAW_EVENT(rawir); if (n == 0 || n % sizeof(int)) { ; return -EINVAL; } count = n / sizeof(int); for (i = 0; i < count; i++) total_duration += abs(txbuf[i]); if (total_duration == 0) { ; return -EINVAL; } if (lodev->txcarrier < lodev->rxcarriermin || lodev->txcarrier > lodev->rxcarriermax) { ; goto out; } if (lodev->learning) rxmask = RXMASK_LEARNING; else rxmask = RXMASK_REGULAR; if (!(rxmask & lodev->txmask)) { ; goto out; } for (i = 0; i < count; i++) { rawir.pulse = i % 2 ? false : true; rawir.duration = abs(txbuf[i]) * 1000; if (rawir.duration) ir_raw_event_store_with_filter(dev, &rawir); } /* Fake a silence long enough to cause us to go idle */ rawir.pulse = false; rawir.duration = dev->timeout; ir_raw_event_store_with_filter(dev, &rawir); ir_raw_event_handle(dev); out: /* Lirc expects this function to take as long as the total duration */ set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(usecs_to_jiffies(total_duration)); return n; }
/* 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); } }
static void saa716x_ir_raw_decode_timer_end(unsigned long data) { struct saa716x_dev *saa716x = (struct saa716x_dev *)data; struct saa716x_ir *ir = saa716x->ir; ir_raw_event_handle(saa716x->ir->rc); ir->active = false; }
static void serial_ir_timeout(unsigned long arg) { DEFINE_IR_RAW_EVENT(ev); ev.timeout = true; ev.duration = serial_ir.rcdev->timeout; ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); ir_raw_event_handle(serial_ir.rcdev); }
static void redrat3_process_ir_data(struct redrat3_dev *rr3) { DEFINE_IR_RAW_EVENT(rawir); struct device *dev; unsigned int i, sig_size, single_len, offset, val; u32 mod_freq; dev = rr3->dev; mod_freq = redrat3_val_to_mod_freq(&rr3->irdata); dev_dbg(dev, "Got mod_freq of %u\n", mod_freq); if (mod_freq && rr3->wideband) { DEFINE_IR_RAW_EVENT(ev); ev.carrier_report = 1; ev.carrier = mod_freq; ir_raw_event_store(rr3->rc, &ev); } /* process each rr3 encoded byte into an int */ sig_size = be16_to_cpu(rr3->irdata.sig_size); for (i = 0; i < sig_size; i++) { offset = rr3->irdata.sigdata[i]; val = get_unaligned_be16(&rr3->irdata.lens[offset]); single_len = redrat3_len_to_us(val); /* we should always get pulse/space/pulse/space samples */ if (i % 2) rawir.pulse = false; else rawir.pulse = true; rawir.duration = US_TO_NS(single_len); /* cap the value to IR_MAX_DURATION */ rawir.duration = (rawir.duration > IR_MAX_DURATION) ? IR_MAX_DURATION : rawir.duration; dev_dbg(dev, "storing %s with duration %d (i: %d)\n", rawir.pulse ? "pulse" : "space", rawir.duration, i); ir_raw_event_store_with_filter(rr3->rc, &rawir); } /* add a trailing space */ rawir.pulse = false; rawir.timeout = true; rawir.duration = rr3->rc->timeout; dev_dbg(dev, "storing trailing timeout with duration %d\n", rawir.duration); ir_raw_event_store_with_filter(rr3->rc, &rawir); dev_dbg(dev, "calling ir_raw_event_handle\n"); ir_raw_event_handle(rr3->rc); }
static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count) { struct loopback_dev *lodev = dev->priv; u32 rxmask; unsigned total_duration = 0; unsigned i; DEFINE_IR_RAW_EVENT(rawir); for (i = 0; i < count; i++) total_duration += abs(txbuf[i]); if (total_duration == 0) { dprintk("invalid tx data, total duration zero\n"); return -EINVAL; } if (lodev->txcarrier < lodev->rxcarriermin || lodev->txcarrier > lodev->rxcarriermax) { dprintk("ignoring tx, carrier out of range\n"); goto out; } if (lodev->learning) rxmask = RXMASK_LEARNING; else rxmask = RXMASK_REGULAR; if (!(rxmask & lodev->txmask)) { dprintk("ignoring tx, rx mask mismatch\n"); goto out; } for (i = 0; i < count; i++) { rawir.pulse = i % 2 ? false : true; rawir.duration = txbuf[i] * 1000; if (rawir.duration) ir_raw_event_store_with_filter(dev, &rawir); } rawir.pulse = false; rawir.duration = dev->timeout; ir_raw_event_store_with_filter(dev, &rawir); ir_raw_event_handle(dev); out: set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(usecs_to_jiffies(total_duration)); return count; }
void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) { int i; const s32 *samples = (const void *)buf; for (i = 0; i < len >> 2; i++) { struct ir_raw_event ev; ev.duration = abs(samples[i]) * 1000; /* Convert to ns */ ev.pulse = (samples[i] > 0) ? false : true; ir_raw_event_store(coredev->ir.input_dev, &ev); } ir_raw_event_handle(coredev->ir.input_dev); }
void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) { int i; const s32 *samples = (const void *)buf; for (i = 0; i < len >> 2; i++) { DEFINE_IR_RAW_EVENT(ev); ev.duration = abs(samples[i]) * 1000; ev.pulse = (samples[i] > 0) ? false : true; ir_raw_event_store(coredev->ir.dev, &ev); } ir_raw_event_handle(coredev->ir.dev); }
/* decode raw bytes as received by the hardware, and push them to the ir-core * layer */ static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int length) { u32 sample_period; unsigned long *ldata; unsigned int next_one, next_zero, size; DEFINE_IR_RAW_EVENT(ev); if (length == 0) return; sample_period = dev->params.sample_period; ldata = (unsigned long *)data; size = length << 3; next_one = find_next_bit_le(ldata, size, 0); if (next_one > 0) { ev.pulse = true; ev.duration = ITE_BITS_TO_NS(next_one, sample_period); ir_raw_event_store_with_filter(dev->rdev, &ev); } while (next_one < size) { next_zero = find_next_zero_bit_le(ldata, size, next_one + 1); ev.pulse = false; ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period); ir_raw_event_store_with_filter(dev->rdev, &ev); if (next_zero < size) { next_one = find_next_bit_le(ldata, size, next_zero + 1); ev.pulse = true; ev.duration = ITE_BITS_TO_NS(next_one - next_zero, sample_period); ir_raw_event_store_with_filter (dev->rdev, &ev); } else next_one = size; } ir_raw_event_handle(dev->rdev); ite_dbg_verbose("decoded %d bytes.", length); }
/* timer callback to send long trailing space on receive timeout */ static void redrat3_rx_timeout(unsigned long data) { struct redrat3_dev *rr3 = (struct redrat3_dev *)data; DEFINE_IR_RAW_EVENT(rawir); rawir.pulse = false; rawir.duration = rr3->rc->timeout; rr3_dbg(rr3->dev, "storing trailing space with duration %d\n", rawir.duration); ir_raw_event_store_with_filter(rr3->rc, &rawir); rr3_dbg(rr3->dev, "calling ir_raw_event_handle\n"); ir_raw_event_handle(rr3->rc); rr3_dbg(rr3->dev, "calling ir_raw_event_reset\n"); ir_raw_event_reset(rr3->rc); }
static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len) { DEFINE_IR_RAW_EVENT(rawir); unsigned i, start, overflow; dev_dbg(ir->dev, "irdata: %*ph (len=%u)", len, ir->buf_in, len); /* * If more than 36 pulses and spaces follow each other, the igorplugusb * overwrites its buffer from the beginning. The overflow value is the * last offset which was not overwritten. Everything from this offset * onwards occurred before everything until this offset. */ overflow = ir->buf_in[2]; i = start = overflow + HEADERLEN; if (start >= len) { dev_err(ir->dev, "receive overflow invalid: %u", overflow); } else { if (overflow > 0) dev_warn(ir->dev, "receive overflow, at least %u lost", overflow); do { rawir.duration = ir->buf_in[i] * 85333; rawir.pulse = i & 1; ir_raw_event_store_with_filter(ir->rc, &rawir); if (++i == len) i = HEADERLEN; } while (i != start); /* add a trailing space */ rawir.duration = ir->rc->timeout; rawir.pulse = false; ir_raw_event_store_with_filter(ir->rc, &rawir); ir_raw_event_handle(ir->rc); } igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY); }
static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id) { unsigned long status; unsigned char dt; unsigned int cnt, rc; struct sunxi_ir *ir = dev_id; DEFINE_IR_RAW_EVENT(rawir); spin_lock(&ir->ir_lock); status = readl(ir->base + SUNXI_IR_RXSTA_REG); /* clean all pending statuses */ writel(status | REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); if (status & (REG_RXINT_RAI_EN | REG_RXINT_RPEI_EN)) { /* How many messages in fifo */ rc = REG_RXSTA_GET_AC(status); /* Sanity check */ rc = rc > ir->fifo_size ? ir->fifo_size : rc; /* If we have data */ for (cnt = 0; cnt < rc; cnt++) { /* for each bit in fifo */ dt = readb(ir->base + SUNXI_IR_RXFIFO_REG); rawir.pulse = (dt & 0x80) != 0; rawir.duration = ((dt & 0x7f) + 1) * SUNXI_IR_SAMPLE; ir_raw_event_store_with_filter(ir->rc, &rawir); } } if (status & REG_RXINT_ROI_EN) { ir_raw_event_reset(ir->rc); } else if (status & REG_RXINT_RPEI_EN) { ir_raw_event_set_idle(ir->rc, true); ir_raw_event_handle(ir->rc); } spin_unlock(&ir->ir_lock); return IRQ_HANDLED; }
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); } }
static irqreturn_t meson_ir_irq(int irqno, void *dev_id) { struct meson_ir *ir = dev_id; u32 duration; DEFINE_IR_RAW_EVENT(rawir); spin_lock(&ir->lock); duration = readl(ir->reg + IR_DEC_REG1); duration = (duration & REG1_TIME_IV_MASK) >> REG1_TIME_IV_SHIFT; rawir.duration = US_TO_NS(duration * MESON_TRATE); rawir.pulse = !!(readl(ir->reg + IR_DEC_STATUS) & STATUS_IR_DEC_IN); ir_raw_event_store_with_filter(ir->rc, &rawir); ir_raw_event_handle(ir->rc); spin_unlock(&ir->lock); return IRQ_HANDLED; }
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; }
static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count) { struct loopback_dev *lodev = dev->priv; u32 rxmask; unsigned i; DEFINE_IR_RAW_EVENT(rawir); if (lodev->txcarrier < lodev->rxcarriermin || lodev->txcarrier > lodev->rxcarriermax) { dprintk("ignoring tx, carrier out of range\n"); goto out; } if (lodev->learning) rxmask = RXMASK_LEARNING; else rxmask = RXMASK_REGULAR; if (!(rxmask & lodev->txmask)) { dprintk("ignoring tx, rx mask mismatch\n"); goto out; } for (i = 0; i < count; i++) { rawir.pulse = i % 2 ? false : true; rawir.duration = txbuf[i] * 1000; if (rawir.duration) ir_raw_event_store_with_filter(dev, &rawir); } /* Fake a silence long enough to cause us to go idle */ rawir.pulse = false; rawir.duration = dev->timeout; ir_raw_event_store_with_filter(dev, &rawir); ir_raw_event_handle(dev); out: return count; }
static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) { struct gpio_rc_dev *gpio_dev = dev_id; unsigned int gval; int rc = 0; enum raw_event_type type = IR_SPACE; if (!gpio_dev->pm_qos_vote && gpio_dev->can_wakeup) { gpio_dev->pm_qos_vote = 1; pm_qos_update_request(&gpio_dev->pm_qos_req, gpio_dev->gpio_irq_latency); } if (gpio_dev->can_sleep) gval = gpio_get_value_cansleep(gpio_dev->gpio_nr); else gval = gpio_get_value(gpio_dev->gpio_nr); if (gval < 0) goto err_get_value; if (gpio_dev->active_low) gval = !gval; if (gval == 1) type = IR_PULSE; rc = ir_raw_event_store_edge(gpio_dev->rcdev, type); if (rc < 0) goto err_get_value; ir_raw_event_handle(gpio_dev->rcdev); if (gpio_dev->can_wakeup) mod_timer(&gpio_dev->gpio_ir_timer, jiffies + msecs_to_jiffies(gpio_ir_timeout)); err_get_value: return IRQ_HANDLED; }
static void wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device) { u8 irdata; DEFINE_IR_RAW_EVENT(rawir); /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) { irdata = inb(data->sbase + WBCIR_REG_SP3_RXDATA); if (data->rxstate == WBCIR_RXSTATE_ERROR) continue; rawir.pulse = irdata & 0x80 ? false : true; rawir.duration = US_TO_NS((irdata & 0x7F) * 10); ir_raw_event_store_with_filter(data->dev, &rawir); } /* Check if we should go idle */ if (data->dev->idle) { led_trigger_event(data->rxtrigger, LED_OFF); data->rxstate = WBCIR_RXSTATE_INACTIVE; } ir_raw_event_handle(data->dev); }
static void redrat3_process_ir_data(struct redrat3_dev *rr3) { DEFINE_IR_RAW_EVENT(rawir); struct redrat3_signal_header header; struct device *dev; int i, trailer = 0; unsigned long delay; u32 mod_freq, single_len; u16 *len_vals; u8 *data_vals; u32 tmp32; u16 tmp16; char *sig_data; if (!rr3) { pr_err("%s called with no context!\n", __func__); return; } rr3_ftr(rr3->dev, "Entered %s\n", __func__); dev = rr3->dev; sig_data = rr3->pbuf; header.length = rr3->pktlen; header.transfer_type = rr3->pkttype; /* */ if (!(header.length >= RR3_HEADER_LENGTH)) dev_warn(dev, "read returned less than rr3 header len\n"); /* */ delay = usecs_to_jiffies(rr3->hw_timeout); mod_timer(&rr3->rx_timeout, jiffies + delay); memcpy(&tmp32, sig_data + RR3_PAUSE_OFFSET, sizeof(tmp32)); header.pause = be32_to_cpu(tmp32); memcpy(&tmp16, sig_data + RR3_FREQ_COUNT_OFFSET, sizeof(tmp16)); header.mod_freq_count = be16_to_cpu(tmp16); memcpy(&tmp16, sig_data + RR3_NUM_PERIOD_OFFSET, sizeof(tmp16)); header.no_periods = be16_to_cpu(tmp16); header.max_lengths = sig_data[RR3_MAX_LENGTHS_OFFSET]; header.no_lengths = sig_data[RR3_NUM_LENGTHS_OFFSET]; memcpy(&tmp16, sig_data + RR3_MAX_SIGS_OFFSET, sizeof(tmp16)); header.max_sig_size = be16_to_cpu(tmp16); memcpy(&tmp16, sig_data + RR3_NUM_SIGS_OFFSET, sizeof(tmp16)); header.sig_size = be16_to_cpu(tmp16); header.no_repeats= sig_data[RR3_REPEATS_OFFSET]; if (debug) { redrat3_dump_signal_header(&header); redrat3_dump_signal_data(sig_data, header.sig_size); } mod_freq = redrat3_val_to_mod_freq(&header); rr3_dbg(dev, "Got mod_freq of %u\n", mod_freq); /* */ len_vals = (u16 *)(sig_data + RR3_HEADER_LENGTH); data_vals = sig_data + RR3_HEADER_LENGTH + (header.max_lengths * sizeof(u16)); /* */ for (i = 0; i < header.sig_size; i++) { u16 val = len_vals[data_vals[i]]; single_len = redrat3_len_to_us((u32)be16_to_cpu(val)); /* */ if (i % 2) rawir.pulse = false; else rawir.pulse = true; rawir.duration = US_TO_NS(single_len); /* */ if (i == 0) trailer = rawir.duration; /* */ rawir.duration &= IR_MAX_DURATION; rr3_dbg(dev, "storing %s with duration %d (i: %d)\n", rawir.pulse ? "pulse" : "space", rawir.duration, i); ir_raw_event_store_with_filter(rr3->rc, &rawir); } /* */ if (i % 2) { rawir.pulse = false; /* */ if (trailer < US_TO_NS(1000)) rawir.duration = US_TO_NS(2800); else rawir.duration = trailer; rr3_dbg(dev, "storing trailing space with duration %d\n", rawir.duration); ir_raw_event_store_with_filter(rr3->rc, &rawir); } rr3_dbg(dev, "calling ir_raw_event_handle\n"); ir_raw_event_handle(rr3->rc); return; }
static irqreturn_t serial_ir_irq_handler(int i, void *blah) { ktime_t kt; int counter, dcd; u8 status; ktime_t delkt; unsigned int data; static int last_dcd = -1; if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { /* not our interrupt */ return IRQ_NONE; } counter = 0; do { counter++; status = sinp(UART_MSR); if (counter > RS_ISR_PASS_LIMIT) { dev_err(&serial_ir.pdev->dev, "Trapped in interrupt"); break; } if ((status & hardware[type].signal_pin_change) && sense != -1) { /* get current time */ kt = ktime_get(); /* * The driver needs to know if your receiver is * active high or active low, or the space/pulse * sense could be inverted. */ /* calc time since last interrupt in nanoseconds */ dcd = (status & hardware[type].signal_pin) ? 1 : 0; if (dcd == last_dcd) { dev_err(&serial_ir.pdev->dev, "ignoring spike: %d %d %lldns %lldns\n", dcd, sense, ktime_to_ns(kt), ktime_to_ns(serial_ir.lastkt)); continue; } delkt = ktime_sub(kt, serial_ir.lastkt); if (ktime_compare(delkt, ktime_set(15, 0)) > 0) { data = IR_MAX_DURATION; /* really long time */ if (!(dcd ^ sense)) { /* sanity check */ dev_err(&serial_ir.pdev->dev, "dcd unexpected: %d %d %lldns %lldns\n", dcd, sense, ktime_to_ns(kt), ktime_to_ns(serial_ir.lastkt)); /* * detecting pulse while this * MUST be a space! */ sense = sense ? 0 : 1; } } else { data = ktime_to_ns(delkt); } frbwrite(data, !(dcd ^ sense)); serial_ir.lastkt = kt; last_dcd = dcd; } } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ mod_timer(&serial_ir.timeout_timer, jiffies + nsecs_to_jiffies(serial_ir.rcdev->timeout)); ir_raw_event_handle(serial_ir.rcdev); return IRQ_HANDLED; }
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); } }
static void redrat3_process_ir_data(struct redrat3_dev *rr3) { DEFINE_IR_RAW_EVENT(rawir); struct device *dev; unsigned i, trailer = 0; unsigned sig_size, single_len, offset, val; unsigned long delay; u32 mod_freq; if (!rr3) { pr_err("%s called with no context!\n", __func__); return; } rr3_ftr(rr3->dev, "Entered %s\n", __func__); dev = rr3->dev; /* Make sure we reset the IR kfifo after a bit of inactivity */ delay = usecs_to_jiffies(rr3->hw_timeout); mod_timer(&rr3->rx_timeout, jiffies + delay); mod_freq = redrat3_val_to_mod_freq(&rr3->irdata); rr3_dbg(dev, "Got mod_freq of %u\n", mod_freq); /* process each rr3 encoded byte into an int */ sig_size = be16_to_cpu(rr3->irdata.sig_size); for (i = 0; i < sig_size; i++) { offset = rr3->irdata.sigdata[i]; val = get_unaligned_be16(&rr3->irdata.lens[offset]); single_len = redrat3_len_to_us(val); /* we should always get pulse/space/pulse/space samples */ if (i % 2) rawir.pulse = false; else rawir.pulse = true; rawir.duration = US_TO_NS(single_len); /* Save initial pulse length to fudge trailer */ if (i == 0) trailer = rawir.duration; /* cap the value to IR_MAX_DURATION */ rawir.duration &= IR_MAX_DURATION; rr3_dbg(dev, "storing %s with duration %d (i: %d)\n", rawir.pulse ? "pulse" : "space", rawir.duration, i); ir_raw_event_store_with_filter(rr3->rc, &rawir); } /* add a trailing space, if need be */ if (i % 2) { rawir.pulse = false; /* this duration is made up, and may not be ideal... */ if (trailer < US_TO_NS(1000)) rawir.duration = US_TO_NS(2800); else rawir.duration = trailer; rr3_dbg(dev, "storing trailing space with duration %d\n", rawir.duration); ir_raw_event_store_with_filter(rr3->rc, &rawir); } rr3_dbg(dev, "calling ir_raw_event_handle\n"); ir_raw_event_handle(rr3->rc); }
static irqreturn_t st_rc_rx_interrupt(int irq, void *data) { unsigned int symbol, mark = 0; struct st_rc_device *dev = data; int last_symbol = 0; u32 status; DEFINE_IR_RAW_EVENT(ev); if (dev->irq_wake) pm_wakeup_event(dev->dev, 0); status = readl(dev->rx_base + IRB_RX_STATUS); while (status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW)) { u32 int_status = readl(dev->rx_base + IRB_RX_INT_STATUS); if (unlikely(int_status & IRB_RX_OVERRUN_INT)) { /* discard the entire collection in case of errors! */ ir_raw_event_reset(dev->rdev); dev_info(dev->dev, "IR RX overrun\n"); writel(IRB_RX_OVERRUN_INT, dev->rx_base + IRB_RX_INT_CLEAR); continue; } symbol = readl(dev->rx_base + IRB_RX_SYS); mark = readl(dev->rx_base + IRB_RX_ON); if (symbol == IRB_TIMEOUT) last_symbol = 1; /* Ignore any noise */ if ((mark > 2) && (symbol > 1)) { symbol -= mark; if (dev->overclocking) { /* adjustments to timings */ symbol *= dev->sample_mult; symbol /= dev->sample_div; mark *= dev->sample_mult; mark /= dev->sample_div; } ev.duration = US_TO_NS(mark); ev.pulse = true; ir_raw_event_store(dev->rdev, &ev); if (!last_symbol) { ev.duration = US_TO_NS(symbol); ev.pulse = false; ir_raw_event_store(dev->rdev, &ev); } else { st_rc_send_lirc_timeout(dev->rdev); } } last_symbol = 0; status = readl(dev->rx_base + IRB_RX_STATUS); } writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_CLEAR); /* Empty software fifo */ ir_raw_event_handle(dev->rdev); return IRQ_HANDLED; }
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; }