Beispiel #1
0
/* initialize the hardware */
static void it8709_init_hardware(struct ite_dev *dev)
{
	ite_dbg("%s called", __func__);

	/* disable all the interrupts */
	it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
			~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
		  IT85_C0IER);

	/* program the baud rate divisor */
	it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR);
	it8709_wr(dev, (ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
			IT85_C0BDHR);

	/* program the C0MSTCR register defaults */
	it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) &
			~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL
			  | IT85_FIFOCLR | IT85_RESET)) | IT85_FIFOTL_DEFAULT,
		  IT85_C0MSTCR);

	/* program the C0RCR register defaults */
	it8709_wr(dev, (it8709_rr(dev, IT85_C0RCR) &
			~(IT85_RXEN | IT85_RDWOS | IT85_RXEND | IT85_RXACT
			  | IT85_RXDCR)) | ITE_RXDCR_DEFAULT,
		  IT85_C0RCR);

	/* program the C0TCR register defaults */
	it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR) & ~(IT85_TXMPM | IT85_TXMPW))
			| IT85_TXRLE | IT85_TXENDF | IT85_TXMPM_DEFAULT
			| IT85_TXMPW_DEFAULT,
		  IT85_C0TCR);

	/* program the carrier parameters */
	ite_set_carrier_params(dev);
}
Beispiel #2
0
/* initialize the hardware */
static void it87_init_hardware(struct ite_dev *dev)
{
	ite_dbg("%s called", __func__);

	/* enable just the baud rate divisor register,
	disabling all the interrupts at the same time */
	outb((inb(dev->cir_addr + IT87_IER) &
		~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE)) | IT87_BR,
		dev->cir_addr + IT87_IER);

	/* write out the baud rate divisor */
	outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT87_BDLR);
	outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff, dev->cir_addr + IT87_BDHR);

	/* disable the baud rate divisor register again */
	outb(inb(dev->cir_addr + IT87_IER) & ~IT87_BR,
		dev->cir_addr + IT87_IER);

	/* program the RCR register defaults */
	outb(ITE_RXDCR_DEFAULT, dev->cir_addr + IT87_RCR);

	/* program the TCR1 register */
	outb(IT87_TXMPM_DEFAULT | IT87_TXENDF | IT87_TXRLE
		| IT87_FIFOTL_DEFAULT | IT87_FIFOCLR,
		dev->cir_addr + IT87_TCR1);

	/* program the carrier parameters */
	ite_set_carrier_params(dev);
}
static void it87_init_hardware(struct ite_dev *dev)
{
	ite_dbg("%s called", __func__);

	outb((inb(dev->cir_addr + IT87_IER) &
		~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE)) | IT87_BR,
		dev->cir_addr + IT87_IER);

	
	outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT87_BDLR);
	outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff, dev->cir_addr + IT87_BDHR);

	
	outb(inb(dev->cir_addr + IT87_IER) & ~IT87_BR,
		dev->cir_addr + IT87_IER);

	
	outb(ITE_RXDCR_DEFAULT, dev->cir_addr + IT87_RCR);

	
	outb(IT87_TXMPM_DEFAULT | IT87_TXENDF | IT87_TXRLE
		| IT87_FIFOTL_DEFAULT | IT87_FIFOCLR,
		dev->cir_addr + IT87_TCR1);

	
	ite_set_carrier_params(dev);
}
static void it8709_init_hardware(struct ite_dev *dev)
{
	ite_dbg("%s called", __func__);

	
	it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
			~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
		  IT85_C0IER);

	
	it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR);
	it8709_wr(dev, (ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
			IT85_C0BDHR);

	
	it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) &
			~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL
			  | IT85_FIFOCLR | IT85_RESET)) | IT85_FIFOTL_DEFAULT,
		  IT85_C0MSTCR);

	
	it8709_wr(dev, (it8709_rr(dev, IT85_C0RCR) &
			~(IT85_RXEN | IT85_RDWOS | IT85_RXEND | IT85_RXACT
			  | IT85_RXDCR)) | ITE_RXDCR_DEFAULT,
		  IT85_C0RCR);

	
	it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR) & ~(IT85_TXMPM | IT85_TXMPW))
			| IT85_TXRLE | IT85_TXENDF | IT85_TXMPM_DEFAULT
			| IT85_TXMPW_DEFAULT,
		  IT85_C0TCR);

	
	ite_set_carrier_params(dev);
}
Beispiel #5
0
/* set the tx duty cycle by controlling the pulse width */
static int ite_set_tx_duty_cycle(struct rc_dev *rcdev, u32 duty_cycle)
{
	unsigned long flags;
	struct ite_dev *dev = rcdev->priv;

	spin_lock_irqsave(&dev->lock, flags);
	dev->params.tx_duty_cycle = duty_cycle;
	ite_set_carrier_params(dev);
	spin_unlock_irqrestore(&dev->lock, flags);

	return 0;
}
Beispiel #6
0
/* set the rx carrier freq range, guess it's in Hz... */
static int ite_set_rx_carrier_range(struct rc_dev *rcdev, u32 carrier_low, u32
				    carrier_high)
{
	unsigned long flags;
	struct ite_dev *dev = rcdev->priv;

	spin_lock_irqsave(&dev->lock, flags);
	dev->params.rx_low_carrier_freq = carrier_low;
	dev->params.rx_high_carrier_freq = carrier_high;
	ite_set_carrier_params(dev);
	spin_unlock_irqrestore(&dev->lock, flags);

	return 0;
}
static void it8708_init_hardware(struct ite_dev *dev)
{
	ite_dbg("%s called", __func__);

	
	outb(inb(dev->cir_addr + IT8708_C0IER) &
		~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
		dev->cir_addr + IT8708_C0IER);

	
	outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE,
		dev->cir_addr + IT8708_BANKSEL);

	outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT8708_C0BDLR);
	outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
		   dev->cir_addr + IT8708_C0BDHR);

	outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE,
		   dev->cir_addr + IT8708_BANKSEL);

	
	outb((inb(dev->cir_addr + IT8708_C0MSTCR) &
			~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL |
			  IT85_FIFOCLR | IT85_RESET)) |
		       IT85_FIFOTL_DEFAULT,
		       dev->cir_addr + IT8708_C0MSTCR);

	
	outb((inb(dev->cir_addr + IT8708_C0RCR) &
			~(IT85_RXEN | IT85_RDWOS | IT85_RXEND |
			  IT85_RXACT | IT85_RXDCR)) |
		       ITE_RXDCR_DEFAULT,
		       dev->cir_addr + IT8708_C0RCR);

	
	outb((inb(dev->cir_addr + IT8708_C0TCR) &
			~(IT85_TXMPM | IT85_TXMPW))
		       |IT85_TXRLE | IT85_TXENDF |
		       IT85_TXMPM_DEFAULT | IT85_TXMPW_DEFAULT,
		       dev->cir_addr + IT8708_C0TCR);

	
	ite_set_carrier_params(dev);
}
Beispiel #8
0
/* transmit out IR pulses; what you get here is a batch of alternating
 * pulse/space/pulse/space lengths that we should write out completely through
 * the FIFO, blocking on a full FIFO */
static int ite_tx_ir(struct rc_dev *rcdev, unsigned *txbuf, unsigned n)
{
	unsigned long flags;
	struct ite_dev *dev = rcdev->priv;
	bool is_pulse = false;
	int remaining_us, fifo_avail, fifo_remaining, last_idx = 0;
	int max_rle_us, next_rle_us;
	int ret = n;
	u8 last_sent[ITE_TX_FIFO_LEN];
	u8 val;

	ite_dbg("%s called", __func__);

	/* clear the array just in case */
	memset(last_sent, 0, ARRAY_SIZE(last_sent));

	spin_lock_irqsave(&dev->lock, flags);

	/* let everybody know we're now transmitting */
	dev->transmitting = true;

	/* and set the carrier values for transmission */
	ite_set_carrier_params(dev);

	/* calculate how much time we can send in one byte */
	max_rle_us =
	    (ITE_BAUDRATE_DIVISOR * dev->params.sample_period *
	     ITE_TX_MAX_RLE) / 1000;

	/* disable the receiver */
	dev->params.disable_rx(dev);

	/* this is where we'll begin filling in the FIFO, until it's full.
	 * then we'll just activate the interrupt, wait for it to wake us up
	 * again, disable it, continue filling the FIFO... until everything
	 * has been pushed out */
	fifo_avail =
	    ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);

	while (n > 0 && dev->in_use) {
		/* transmit the next sample */
		is_pulse = !is_pulse;
		remaining_us = *(txbuf++);
		n--;

		ite_dbg("%s: %ld",
				      ((is_pulse) ? "pulse" : "space"),
				      (long int)
				      remaining_us);

		/* repeat while the pulse is non-zero length */
		while (remaining_us > 0 && dev->in_use) {
			if (remaining_us > max_rle_us)
				next_rle_us = max_rle_us;

			else
				next_rle_us = remaining_us;

			remaining_us -= next_rle_us;

			/* check what's the length we have to pump out */
			val = (ITE_TX_MAX_RLE * next_rle_us) / max_rle_us;

			/* put it into the sent buffer */
			last_sent[last_idx++] = val;
			last_idx &= (ITE_TX_FIFO_LEN);

			/* encode it for 7 bits */
			val = (val - 1) & ITE_TX_RLE_MASK;

			/* take into account pulse/space prefix */
			if (is_pulse)
				val |= ITE_TX_PULSE;

			else
				val |= ITE_TX_SPACE;

			/*
			 * if we get to 0 available, read again, just in case
			 * some other slot got freed
			 */
			if (fifo_avail <= 0)
				fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);

			/* if it's still full */
			if (fifo_avail <= 0) {
				/* enable the tx interrupt */
				dev->params.
				enable_tx_interrupt(dev);

				/* drop the spinlock */
				spin_unlock_irqrestore(&dev->lock, flags);

				/* wait for the FIFO to empty enough */
				wait_event_interruptible(dev->tx_queue, (fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev)) >= 8);

				/* get the spinlock again */
				spin_lock_irqsave(&dev->lock, flags);

				/* disable the tx interrupt again. */
				dev->params.
				disable_tx_interrupt(dev);
			}

			/* now send the byte through the FIFO */
			dev->params.put_tx_byte(dev, val);
			fifo_avail--;
		}
	}

	/* wait and don't return until the whole FIFO has been sent out;
	 * otherwise we could configure the RX carrier params instead of the
	 * TX ones while the transmission is still being performed! */
	fifo_remaining = dev->params.get_tx_used_slots(dev);
	remaining_us = 0;
	while (fifo_remaining > 0) {
		fifo_remaining--;
		last_idx--;
		last_idx &= (ITE_TX_FIFO_LEN - 1);
		remaining_us += last_sent[last_idx];
	}
	remaining_us = (remaining_us * max_rle_us) / (ITE_TX_MAX_RLE);

	/* drop the spinlock while we sleep */
	spin_unlock_irqrestore(&dev->lock, flags);

	/* sleep remaining_us microseconds */
	mdelay(DIV_ROUND_UP(remaining_us, 1000));

	/* reacquire the spinlock */
	spin_lock_irqsave(&dev->lock, flags);

	/* now we're not transmitting anymore */
	dev->transmitting = false;

	/* and set the carrier values for reception */
	ite_set_carrier_params(dev);

	/* reenable the receiver */
	if (dev->in_use)
		dev->params.enable_rx(dev);

	/* notify transmission end */
	wake_up_interruptible(&dev->tx_ended);

	spin_unlock_irqrestore(&dev->lock, flags);

	return ret;
}
static int ite_tx_ir(struct rc_dev *rcdev, unsigned *txbuf, unsigned n)
{
	unsigned long flags;
	struct ite_dev *dev = rcdev->priv;
	bool is_pulse = false;
	int remaining_us, fifo_avail, fifo_remaining, last_idx = 0;
	int max_rle_us, next_rle_us;
	int ret = n;
	u8 last_sent[ITE_TX_FIFO_LEN];
	u8 val;

	ite_dbg("%s called", __func__);

	
	memset(last_sent, 0, ARRAY_SIZE(last_sent));

	spin_lock_irqsave(&dev->lock, flags);

	
	dev->transmitting = true;

	
	ite_set_carrier_params(dev);

	
	max_rle_us =
	    (ITE_BAUDRATE_DIVISOR * dev->params.sample_period *
	     ITE_TX_MAX_RLE) / 1000;

	
	dev->params.disable_rx(dev);

	fifo_avail =
	    ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);

	while (n > 0 && dev->in_use) {
		
		is_pulse = !is_pulse;
		remaining_us = *(txbuf++);
		n--;

		ite_dbg("%s: %ld",
				      ((is_pulse) ? "pulse" : "space"),
				      (long int)
				      remaining_us);

		
		while (remaining_us > 0 && dev->in_use) {
			if (remaining_us > max_rle_us)
				next_rle_us = max_rle_us;

			else
				next_rle_us = remaining_us;

			remaining_us -= next_rle_us;

			
			val = (ITE_TX_MAX_RLE * next_rle_us) / max_rle_us;

			
			last_sent[last_idx++] = val;
			last_idx &= (ITE_TX_FIFO_LEN);

			
			val = (val - 1) & ITE_TX_RLE_MASK;

			
			if (is_pulse)
				val |= ITE_TX_PULSE;

			else
				val |= ITE_TX_SPACE;

			if (fifo_avail <= 0)
				fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);

			
			if (fifo_avail <= 0) {
				
				dev->params.
				enable_tx_interrupt(dev);

				
				spin_unlock_irqrestore(&dev->lock, flags);

				
				wait_event_interruptible(dev->tx_queue, (fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev)) >= 8);

				
				spin_lock_irqsave(&dev->lock, flags);

				
				dev->params.
				disable_tx_interrupt(dev);
			}

			
			dev->params.put_tx_byte(dev, val);
			fifo_avail--;
		}
	}

	fifo_remaining = dev->params.get_tx_used_slots(dev);
	remaining_us = 0;
	while (fifo_remaining > 0) {
		fifo_remaining--;
		last_idx--;
		last_idx &= (ITE_TX_FIFO_LEN - 1);
		remaining_us += last_sent[last_idx];
	}
	remaining_us = (remaining_us * max_rle_us) / (ITE_TX_MAX_RLE);

	
	spin_unlock_irqrestore(&dev->lock, flags);

	
	mdelay(DIV_ROUND_UP(remaining_us, 1000));

	
	spin_lock_irqsave(&dev->lock, flags);

	
	dev->transmitting = false;

	
	ite_set_carrier_params(dev);

	
	if (dev->in_use)
		dev->params.enable_rx(dev);

	
	wake_up_interruptible(&dev->tx_ended);

	spin_unlock_irqrestore(&dev->lock, flags);

	return ret;
}