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; }
static void frbwrite(unsigned int l, bool is_pulse) { /* simple noise filter */ static unsigned int ptr, pulse, space; DEFINE_IR_RAW_EVENT(ev); if (ptr > 0 && is_pulse) { pulse += l; if (pulse > 250000) { ev.duration = space; ev.pulse = false; ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); ev.duration = pulse; ev.pulse = true; ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); ptr = 0; pulse = 0; } return; } if (!is_pulse) { if (ptr == 0) { if (l > 20000000) { space = l; ptr++; return; } } else { if (l > 20000000) { space += pulse; if (space > IR_MAX_DURATION) space = IR_MAX_DURATION; space += l; if (space > IR_MAX_DURATION) space = IR_MAX_DURATION; pulse = 0; return; } ev.duration = space; ev.pulse = false; ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); ev.duration = pulse; ev.pulse = true; ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); ptr = 0; pulse = 0; } } ev.duration = l; ev.pulse = is_pulse; ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); }
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; }
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); }
/* 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); }
/* 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 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 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 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; }
/* 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 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; }
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 add_read_queue(int flag, unsigned long val) { DEFINE_IR_RAW_EVENT(ev); pr_debug("add flag %d with val %lu\n", flag, val); /* * statistically, pulses are ~TIME_CONST/2 too long. we could * maybe make this more exact, but this is good enough */ if (flag) { /* pulse */ if (val > TIME_CONST / 2) val -= TIME_CONST / 2; else /* should not ever happen */ val = 1; ev.pulse = true; } else { val += TIME_CONST / 2; } ev.duration = US_TO_NS(val); ir_raw_event_store_with_filter(rcdev, &ev); }
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 void redrat3_process_ir_data(struct redrat3_dev *rr3) { DEFINE_IR_RAW_EVENT(rawir); struct redrat3_signal_header header; struct device *dev; int i; 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; /* Sanity check */ if (!(header.length >= RR3_HEADER_LENGTH)) dev_warn(dev, "read returned less than rr3 header len\n"); delay = usecs_to_jiffies(rr3->rc->timeout / 1000); 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); /* Here we pull out the 'length' values from the signal */ len_vals = (u16 *)(sig_data + RR3_HEADER_LENGTH); data_vals = sig_data + RR3_HEADER_LENGTH + (header.max_lengths * sizeof(u16)); /* process each rr3 encoded byte into an int */ 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)); /* cap the value to IR_MAX_DURATION */ single_len &= IR_MAX_DURATION; /* 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); 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... */ rawir.duration = rr3->rc->timeout / 2; 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 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 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 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; }