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); }
static u32 redrat3_get_timeout(struct device *dev, struct rc_dev *rc, struct usb_device *udev) { u32 *tmp; u32 timeout = MS_TO_NS(150); /* a sane default, if things go haywire */ int len, ret, pipe; len = sizeof(*tmp); tmp = kzalloc(len, GFP_KERNEL); if (!tmp) { dev_warn(dev, "Memory allocation faillure\n"); return timeout; } pipe = usb_rcvctrlpipe(udev, 0); ret = usb_control_msg(udev, pipe, RR3_GET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); if (ret != len) { dev_warn(dev, "Failed to read timeout from hardware\n"); return timeout; } timeout = US_TO_NS(redrat3_len_to_us(be32_to_cpu(*tmp))); if (timeout < rc->min_timeout) timeout = rc->min_timeout; else if (timeout > rc->max_timeout) timeout = rc->max_timeout; rr3_dbg(dev, "Got timeout of %d ms\n", timeout / (1000 * 1000)); return timeout; }
int init_module(void) { ktime_t ktime; //Initialize tokens tokens=0; //Initialize clock spin_lock_init(&globalLock); //Init PacketQueue q=vmalloc(sizeof(struct PacketQueue)); Init_PacketQueue(q); //Init timer do_gettimeofday(&tv_old); ktime = ktime_set( 0, US_TO_NS(delay_in_us) ); hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); hr_timer.function = &my_hrtimer_callback; hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL ); //POSTROUTING nfho_outgoing.hook = hook_func_out; //function to call when conditions below met nfho_outgoing.hooknum = NF_INET_POST_ROUTING; //called in post_routing nfho_outgoing.pf = PF_INET; //IPV4 packets nfho_outgoing.priority = NF_IP_PRI_FIRST; //set to highest priority over all other hook functions nf_register_hook(&nfho_outgoing); //register hook*/ printk(KERN_INFO "The shaper installing\n"); return 0; }
static enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer ) { ktime_t interval,now; unsigned long flags; //variable for save current states of irq int num=0; while(1) { if(num>8) break; if(q->size>0) { //There are still some packets in queue spin_lock_irqsave(&globalLock,flags); //Dequeue packets Dequeue_PacketQueue(q); spin_unlock_irqrestore(&globalLock,flags); num++; } else { //There is no packet in queue break; } } interval = ktime_set(0, US_TO_NS(delay_in_us)); now = ktime_get(); hrtimer_forward(timer,now,interval); return HRTIMER_RESTART; }
/* 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 struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) { struct device *dev = rr3->dev; struct rc_dev *rc; int ret = -ENODEV; u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct); rc = rc_allocate_device(); if (!rc) { dev_err(dev, "remote input dev allocation failed\n"); goto out; } snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s " "Infrared Remote Transceiver (%04x:%04x)", prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "", le16_to_cpu(rr3->udev->descriptor.idVendor), prod); usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys)); rc->input_name = rr3->name; rc->input_phys = rr3->phys; usb_to_input_id(rr3->udev, &rc->input_id); rc->dev.parent = dev; rc->priv = rr3; rc->driver_type = RC_DRIVER_IR_RAW; rc_set_allowed_protocols(rc, RC_BIT_ALL); rc->timeout = US_TO_NS(2750); rc->tx_ir = redrat3_transmit_ir; rc->s_tx_carrier = redrat3_set_tx_carrier; rc->driver_name = DRIVER_NAME; rc->rx_resolution = US_TO_NS(2); rc->map_name = RC_MAP_HAUPPAUGE; ret = rc_register_device(rc); if (ret < 0) { dev_err(dev, "remote dev registration failed\n"); goto out; } return rc; out: rc_free_device(rc); return NULL; }
static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) { struct device *dev = rr3->dev; struct rc_dev *rc; int ret; u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct); rc = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rc) return NULL; snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s Infrared Remote Transceiver", prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : ""); usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys)); rc->device_name = rr3->name; rc->input_phys = rr3->phys; usb_to_input_id(rr3->udev, &rc->input_id); rc->dev.parent = dev; rc->priv = rr3; rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT); rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT); rc->timeout = US_TO_NS(redrat3_get_timeout(rr3)); rc->s_timeout = redrat3_set_timeout; rc->tx_ir = redrat3_transmit_ir; rc->s_tx_carrier = redrat3_set_tx_carrier; rc->s_carrier_report = redrat3_wideband_receiver; rc->driver_name = DRIVER_NAME; rc->rx_resolution = US_TO_NS(2); rc->map_name = RC_MAP_HAUPPAUGE; ret = rc_register_device(rc); if (ret < 0) { dev_err(dev, "remote dev registration failed\n"); goto out; } return rc; out: rc_free_device(rc); return NULL; }
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 enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer ) { struct timeval tv; //timeval struct used by do_gettimeofday unsigned long time_interval; //time interval ktime_t interval,now; unsigned long flags; //variable for save current states of irq unsigned int len; //Get current time do_gettimeofday(&tv); //Calculate interval time_interval=time_of_interval(tv,tv_old); //Reset tv_old tv_old=tv; //Update tokens tokens=tokens+(time_interval*RATE)/1000000; spin_lock_irqsave(&globalLock,flags); //spin_lock_irq(&globalLock); //spin_lock(&globalLock); while(1) { if(q->size>0) { //There are still some packets in queue len=q->packets[q->head].skb->len; //printk(KERN_INFO "%u\n",len); if(len<=tokens) { //There are enough tokens //Reduce tokens tokens=tokens-len; //Deuqueu packets Dequeue_PacketQueue(q); } else { //There are no enough tokens break; } } else { break; } } //Toekns no larger then bucket size if there are no packets to transmit if(tokens>=BUCKET&&q->size==0) tokens=BUCKET; spin_unlock_irqrestore(&globalLock,flags); //spin_unlock_irq(&globalLock); //spin_unlock(&globalLock); interval = ktime_set( 0, US_TO_NS(delay_in_us)); now = ktime_get(); hrtimer_forward(timer,now,interval); return HRTIMER_RESTART; }
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, status; struct ir_raw_event rawir = {}; spin_lock(&ir->lock); duration = readl_relaxed(ir->reg + IR_DEC_REG1); duration = FIELD_GET(REG1_TIME_IV_MASK, duration); rawir.duration = US_TO_NS(duration * MESON_TRATE); status = readl_relaxed(ir->reg + IR_DEC_STATUS); rawir.pulse = !!(status & STATUS_IR_DEC_IN); ir_raw_event_store_with_timeout(ir->rc, &rawir); spin_unlock(&ir->lock); return IRQ_HANDLED; }
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 wbcir_set_carrier_report(struct rc_dev *dev, int enable) { struct wbcir_data *data = dev->priv; unsigned long flags; spin_lock_irqsave(&data->spinlock, flags); if (data->carrier_report_enabled == enable) { spin_unlock_irqrestore(&data->spinlock, flags); return 0; } data->pulse_duration = 0; wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_R, WBCIR_CNTR_EN | WBCIR_CNTR_R); if (enable && data->dev->idle) wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_EN, WBCIR_CNTR_EN | WBCIR_CNTR_R); /* Set a higher sampling resolution if carrier reports are enabled */ wbcir_select_bank(data, WBCIR_BANK_2); data->dev->rx_resolution = US_TO_NS(enable ? 2 : 10); outb(enable ? 0x03 : 0x0f, data->sbase + WBCIR_REG_SP3_BGDL); outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); /* Enable oversampling if carrier reports are enabled */ wbcir_select_bank(data, WBCIR_BANK_7); wbcir_set_bits(data->sbase + WBCIR_REG_SP3_RCCFG, enable ? WBCIR_RX_T_OV : 0, WBCIR_RX_T_OV); data->carrier_report_enabled = enable; spin_unlock_irqrestore(&data->spinlock, flags); return 0; }
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 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); }
/* initialize CIR input device */ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) { struct rc_dev *rdev; int ret = 0; rdev = rc_allocate_device(); if (!rdev) return -ENOMEM; rdev->priv = data; rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protos = RC_BIT_ALL; rdev->open = picolcd_cir_open; rdev->close = picolcd_cir_close; rdev->input_name = data->hdev->name; rdev->input_phys = data->hdev->phys; rdev->input_id.bustype = data->hdev->bus; rdev->input_id.vendor = data->hdev->vendor; rdev->input_id.product = data->hdev->product; rdev->input_id.version = data->hdev->version; rdev->dev.parent = &data->hdev->dev; rdev->driver_name = PICOLCD_NAME; rdev->map_name = RC_MAP_RC6_MCE; rdev->timeout = MS_TO_NS(100); rdev->rx_resolution = US_TO_NS(1); ret = rc_register_device(rdev); if (ret) goto err; data->rc_dev = rdev; return 0; err: rc_free_device(rdev); 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); } }
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; }
/* Allocate memory, probe hardware, and initialize everything */ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) { struct fintek_dev *fintek; struct rc_dev *rdev; int ret = -ENOMEM; fintek = kzalloc(sizeof(struct fintek_dev), GFP_KERNEL); if (!fintek) return ret; /* input device for IR remote (and tx) */ rdev = rc_allocate_device(); if (!rdev) goto exit_free_dev_rdev; ret = -ENODEV; /* validate pnp resources */ if (!pnp_port_valid(pdev, 0)) { 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, "IR PNP IRQ not valid!\n"); goto exit_free_dev_rdev; } fintek->cir_addr = pnp_port_start(pdev, 0); fintek->cir_irq = pnp_irq(pdev, 0); fintek->cir_port_len = pnp_port_len(pdev, 0); fintek->cr_ip = CR_INDEX_PORT; fintek->cr_dp = CR_DATA_PORT; spin_lock_init(&fintek->fintek_lock); pnp_set_drvdata(pdev, fintek); fintek->pdev = pdev; ret = fintek_hw_detect(fintek); if (ret) goto exit_free_dev_rdev; /* Initialize CIR & CIR Wake Logical Devices */ fintek_config_mode_enable(fintek); fintek_cir_ldev_init(fintek); fintek_config_mode_disable(fintek); /* Initialize CIR & CIR Wake Config Registers */ fintek_cir_regs_init(fintek); /* Set up the rc device */ rdev->priv = fintek; rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = fintek_open; rdev->close = fintek_close; rdev->input_name = FINTEK_DESCRIPTION; rdev->input_phys = "fintek/cir0"; rdev->input_id.bustype = BUS_HOST; rdev->input_id.vendor = VENDOR_ID_FINTEK; rdev->input_id.product = fintek->chip_major; rdev->input_id.version = fintek->chip_minor; rdev->dev.parent = &pdev->dev; rdev->driver_name = FINTEK_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; rdev->timeout = US_TO_NS(1000); /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); fintek->rdev = rdev; ret = -EBUSY; /* now claim resources */ if (!request_region(fintek->cir_addr, fintek->cir_port_len, FINTEK_DRIVER_NAME)) goto exit_free_dev_rdev; if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, FINTEK_DRIVER_NAME, (void *)fintek)) goto exit_free_cir_addr; ret = rc_register_device(rdev); if (ret) goto exit_free_irq; device_init_wakeup(&pdev->dev, true); fit_pr(KERN_NOTICE, "driver has been successfully loaded\n"); if (debug) cir_dump_regs(fintek); return 0; exit_free_irq: free_irq(fintek->cir_irq, fintek); exit_free_cir_addr: release_region(fintek->cir_addr, fintek->cir_port_len); exit_free_dev_rdev: rc_free_device(rdev); kfree(fintek); return ret; }
static int meson_ir_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct resource *res; const char *map_name; struct meson_ir *ir; int ret; ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL); if (!ir) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ir->reg = devm_ioremap_resource(dev, res); if (IS_ERR(ir->reg)) { dev_err(dev, "failed to map registers\n"); return PTR_ERR(ir->reg); } ir->irq = platform_get_irq(pdev, 0); if (ir->irq < 0) { dev_err(dev, "no irq resource\n"); return ir->irq; } ir->rc = rc_allocate_device(); if (!ir->rc) { dev_err(dev, "failed to allocate rc device\n"); return -ENOMEM; } ir->rc->priv = ir; ir->rc->input_name = DRIVER_NAME; ir->rc->input_phys = DRIVER_NAME "/input0"; ir->rc->input_id.bustype = BUS_HOST; map_name = of_get_property(node, "linux,rc-map-name", NULL); ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; ir->rc->dev.parent = dev; ir->rc->driver_type = RC_DRIVER_IR_RAW; ir->rc->allowed_protocols = RC_BIT_ALL; ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); ir->rc->timeout = MS_TO_NS(200); ir->rc->driver_name = DRIVER_NAME; spin_lock_init(&ir->lock); platform_set_drvdata(pdev, ir); ret = rc_register_device(ir->rc); if (ret) { dev_err(dev, "failed to register rc device\n"); goto out_free; } ret = devm_request_irq(dev, ir->irq, meson_ir_irq, 0, "ir-meson", ir); if (ret) { dev_err(dev, "failed to request irq\n"); goto out_unreg; } /* Reset the decoder */ meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, REG1_RESET); meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, 0); /* Set general operation mode */ meson_ir_set_mask(ir, IR_DEC_REG1, REG1_MODE_MASK, REG1_MODE_GENERAL); /* Set rate */ meson_ir_set_mask(ir, IR_DEC_REG0, REG0_RATE_MASK, MESON_TRATE - 1); /* IRQ on rising and falling edges */ meson_ir_set_mask(ir, IR_DEC_REG1, REG1_IRQSEL_MASK, REG1_IRQSEL_RISE_FALL); /* Enable the decoder */ meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, REG1_ENABLE); dev_info(dev, "receiver initialized\n"); return 0; out_unreg: rc_unregister_device(ir->rc); ir->rc = NULL; out_free: rc_free_device(ir->rc); return ret; }
static int meson_ir_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct resource *res; const char *map_name; struct meson_ir *ir; int irq, ret; ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL); if (!ir) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ir->reg = devm_ioremap_resource(dev, res); if (IS_ERR(ir->reg)) { dev_err(dev, "failed to map registers\n"); return PTR_ERR(ir->reg); } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "no irq resource\n"); return irq; } ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW); if (!ir->rc) { dev_err(dev, "failed to allocate rc device\n"); return -ENOMEM; } ir->rc->priv = ir; ir->rc->device_name = DRIVER_NAME; ir->rc->input_phys = DRIVER_NAME "/input0"; ir->rc->input_id.bustype = BUS_HOST; map_name = of_get_property(node, "linux,rc-map-name", NULL); ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); ir->rc->min_timeout = 1; ir->rc->timeout = IR_DEFAULT_TIMEOUT; ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; ir->rc->driver_name = DRIVER_NAME; spin_lock_init(&ir->lock); platform_set_drvdata(pdev, ir); ret = devm_rc_register_device(dev, ir->rc); if (ret) { dev_err(dev, "failed to register rc device\n"); return ret; } ret = devm_request_irq(dev, irq, meson_ir_irq, 0, NULL, ir); if (ret) { dev_err(dev, "failed to request irq\n"); return ret; } /* Reset the decoder */ meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, REG1_RESET); meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, 0); /* Set general operation mode (= raw/software decoding) */ if (of_device_is_compatible(node, "amlogic,meson6-ir")) meson_ir_set_mask(ir, IR_DEC_REG1, REG1_MODE_MASK, FIELD_PREP(REG1_MODE_MASK, DECODE_MODE_RAW)); else meson_ir_set_mask(ir, IR_DEC_REG2, REG2_MODE_MASK, FIELD_PREP(REG2_MODE_MASK, DECODE_MODE_RAW)); /* Set rate */ meson_ir_set_mask(ir, IR_DEC_REG0, REG0_RATE_MASK, MESON_TRATE - 1); /* IRQ on rising and falling edges */ meson_ir_set_mask(ir, IR_DEC_REG1, REG1_IRQSEL_MASK, FIELD_PREP(REG1_IRQSEL_MASK, REG1_IRQSEL_RISE_FALL)); /* Enable the decoder */ meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, REG1_ENABLE); dev_info(dev, "receiver initialized\n"); return 0; }
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 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 int st_rc_probe(struct platform_device *pdev) { int ret = -EINVAL; struct rc_dev *rdev; struct device *dev = &pdev->dev; struct resource *res; struct st_rc_device *rc_dev; struct device_node *np = pdev->dev.of_node; const char *rx_mode; rc_dev = devm_kzalloc(dev, sizeof(struct st_rc_device), GFP_KERNEL); if (!rc_dev) return -ENOMEM; rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rdev) return -ENOMEM; if (np && !of_property_read_string(np, "rx-mode", &rx_mode)) { if (!strcmp(rx_mode, "uhf")) { rc_dev->rxuhfmode = true; } else if (!strcmp(rx_mode, "infrared")) { rc_dev->rxuhfmode = false; } else { dev_err(dev, "Unsupported rx mode [%s]\n", rx_mode); goto err; } } else { goto err; } rc_dev->sys_clock = devm_clk_get(dev, NULL); if (IS_ERR(rc_dev->sys_clock)) { dev_err(dev, "System clock not found\n"); ret = PTR_ERR(rc_dev->sys_clock); goto err; } rc_dev->irq = platform_get_irq(pdev, 0); if (rc_dev->irq < 0) { ret = rc_dev->irq; goto err; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rc_dev->base = devm_ioremap_resource(dev, res); if (IS_ERR(rc_dev->base)) { ret = PTR_ERR(rc_dev->base); goto err; } if (rc_dev->rxuhfmode) rc_dev->rx_base = rc_dev->base + 0x40; else rc_dev->rx_base = rc_dev->base; rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(rc_dev->rstc)) { ret = PTR_ERR(rc_dev->rstc); goto err; } rc_dev->dev = dev; platform_set_drvdata(pdev, rc_dev); st_rc_hardware_init(rc_dev); rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; /* rx sampling rate is 10Mhz */ rdev->rx_resolution = 100; rdev->timeout = US_TO_NS(MAX_SYMB_TIME); rdev->priv = rc_dev; rdev->open = st_rc_open; rdev->close = st_rc_close; rdev->driver_name = IR_ST_NAME; rdev->map_name = RC_MAP_EMPTY; rdev->device_name = "ST Remote Control Receiver"; ret = rc_register_device(rdev); if (ret < 0) goto clkerr; rc_dev->rdev = rdev; if (devm_request_irq(dev, rc_dev->irq, st_rc_rx_interrupt, 0, IR_ST_NAME, rc_dev) < 0) { dev_err(dev, "IRQ %d register failed\n", rc_dev->irq); ret = -EINVAL; goto rcerr; } /* enable wake via this device */ device_init_wakeup(dev, true); dev_pm_set_wake_irq(dev, rc_dev->irq); /** * for LIRC_MODE_MODE2 or LIRC_MODE_PULSE or LIRC_MODE_RAW * lircd expects a long space first before a signal train to sync. */ st_rc_send_lirc_timeout(rdev); dev_info(dev, "setup in %s mode\n", rc_dev->rxuhfmode ? "UHF" : "IR"); return ret; rcerr: rc_unregister_device(rdev); rdev = NULL; clkerr: clk_disable_unprepare(rc_dev->sys_clock); err: rc_free_device(rdev); dev_err(dev, "Unable to register device (%d)\n", ret); return ret; }
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; }