static void it87_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) { /* determine 'virtual' pulse end: */ pulse_end = delta(&last_tv, &last_intr_tv); #ifdef DEBUG_SIGNAL printk(KERN_DEBUG LIRC_DRIVER_NAME ": timeout add %d for %lu usec\n", last_value, pulse_end); #endif add_read_queue(last_value, pulse_end); last_value = 0; last_tv=last_intr_tv; } spin_unlock_irqrestore(&timer_lock, flags); }
/* 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 void it87_interrupt(int irq, void * dev_id, struct pt_regs * regs) { unsigned char data; struct timeval curr_tv; static unsigned long deltv; unsigned long deltintrtv; unsigned long flags, hw_flags; int iir, lsr; int fifo = 0; iir = inb(io + IT87_CIR_IIR); switch (iir & IT87_CIR_IIR_IID) { case 0x4: case 0x6: lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO | IT87_CIR_RSR_RXFBC); fifo = lsr & IT87_CIR_RSR_RXFBC; #ifdef DEBUG_SIGNAL printk(KERN_DEBUG LIRC_DRIVER_NAME "iir: 0x%x fifo: 0x%x\n", iir, lsr); #endif /* avoid interference with timer */ spin_lock_irqsave(&timer_lock, flags); spin_lock_irqsave(&hardware_lock, hw_flags); do { del_timer(&timerlist); data = inb(io + IT87_CIR_DR); #ifdef DEBUG_SIGNAL printk(KERN_DEBUG LIRC_DRIVER_NAME ": data=%.2x\n", data); #endif do_gettimeofday(&curr_tv); deltv = delta(&last_tv, &curr_tv); deltintrtv = delta(&last_intr_tv, &curr_tv); #ifdef DEBUG_SIGNAL printk(KERN_DEBUG LIRC_DRIVER_NAME ": t %lu , d %d\n", deltintrtv, (int)data); #endif /* if nothing came in last 2 cycles, it was gap */ if (deltintrtv > TIME_CONST * 2) { if (last_value) { #ifdef DEBUG_SIGNAL printk(KERN_DEBUG LIRC_DRIVER_NAME ": GAP\n"); #endif /* simulate signal change */ add_read_queue(last_value, deltv- deltintrtv); last_value = 0; last_tv.tv_sec = last_intr_tv.tv_sec; last_tv.tv_usec = last_intr_tv.tv_usec; deltv = deltintrtv; } } data = 1; if (data ^ last_value) { /* deltintrtv > 2*TIME_CONST, remember ? */ /* the other case is timeout */ add_read_queue(last_value, deltv-TIME_CONST); last_value = data; last_tv = curr_tv; if(last_tv.tv_usec>=TIME_CONST) { last_tv.tv_usec-=TIME_CONST; } else { last_tv.tv_sec--; last_tv.tv_usec+=1000000- TIME_CONST; } } last_intr_tv = curr_tv; if (data) { /* start timer for end of sequence detection */ timerlist.expires = jiffies + IT87_TIMEOUT; add_timer(&timerlist); } outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) | IT87_CIR_RCR_RXACT, io + IT87_CIR_RCR); if (it87_RXEN_mask) { outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, io + IT87_CIR_RCR); } fifo--; } while (fifo != 0); spin_unlock_irqrestore(&hardware_lock, hw_flags); spin_unlock_irqrestore(&timer_lock, flags); break; default: /* not our irq */ #ifdef DEBUG_SIGNAL printk(KERN_DEBUG LIRC_DRIVER_NAME "unknown IRQ (shouldn't happen) !!\n"); #endif break; } }
static irqreturn_t sir_interrupt(int irq, void *dev_id) { unsigned char data; ktime_t curr_time; static unsigned long delt; unsigned long deltintr; unsigned long flags; int counter = 0; int iir, lsr; while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) { if (++counter > 256) { dev_err(&sir_ir_dev->dev, "Trapped in interrupt"); break; } switch (iir & UART_IIR_ID) { /* FIXME toto treba preriedit */ case UART_IIR_MSI: (void)inb(io + UART_MSR); break; case UART_IIR_RLSI: case UART_IIR_THRI: (void)inb(io + UART_LSR); break; case UART_IIR_RDI: /* avoid interference with timer */ spin_lock_irqsave(&timer_lock, flags); do { del_timer(&timerlist); data = inb(io + UART_RX); curr_time = ktime_get(); delt = min_t(unsigned long, ktime_us_delta(last, curr_time), IR_MAX_DURATION); deltintr = min_t(unsigned long, ktime_us_delta(last_intr_time, curr_time), IR_MAX_DURATION); dev_dbg(&sir_ir_dev->dev, "t %lu, d %d\n", deltintr, (int)data); /* * if nothing came in last X cycles, * it was gap */ if (deltintr > TIME_CONST * threshold) { if (last_value) { dev_dbg(&sir_ir_dev->dev, "GAP\n"); /* simulate signal change */ add_read_queue(last_value, delt - deltintr); last_value = 0; last = last_intr_time; delt = deltintr; } } data = 1; if (data ^ last_value) { /* * deltintr > 2*TIME_CONST, remember? * the other case is timeout */ add_read_queue(last_value, delt - TIME_CONST); last_value = data; last = curr_time; last = ktime_sub_us(last, TIME_CONST); } last_intr_time = curr_time; if (data) { /* * start timer for end of * sequence detection */ timerlist.expires = jiffies + SIR_TIMEOUT; add_timer(&timerlist); } lsr = inb(io + UART_LSR); } while (lsr & UART_LSR_DR); /* data ready */ spin_unlock_irqrestore(&timer_lock, flags); break; default: break; } } ir_raw_event_handle(rcdev); return IRQ_RETVAL(IRQ_HANDLED); }