// SPDX-License-Identifier: GPL-2.0-or-later /* * Driver for ITE Tech Inc. IT8712F/IT8512 CIR * * Copyright (C) 2010 Juan Jesús García de Soria <skandalfo@gmail.com> * * Inspired by the original lirc_it87 and lirc_ite8709 drivers, on top of the * skeleton provided by the nuvoton-cir driver. * * The lirc_it87 driver was originally written by Hans-Gunter Lutke Uphues * <hg_lu@web.de> in 2001, with enhancements by Christoph Bartelmus * <lirc@bartelmus.de>, Andrew Calkin <r_tay@hotmail.com> and James Edwards * <jimbo-lirc@edwardsclan.net>. * * The lirc_ite8709 driver was written by Grégory Lardière * <spmf2004-lirc@yahoo.fr> in 2008.
*/
/* override detected model id */ staticint model_number = -1;
module_param(model_number, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(model_number, "Use this model number, don't autodetect");
/* HW-independent code functions */
/* check whether carrier frequency is high frequency */ staticinlinebool ite_is_high_carrier_freq(unsignedint freq)
{ return freq >= ITE_HCF_MIN_CARRIER_FREQ;
}
/* get the bits required to program the carrier frequency in CFQ bits,
* unshifted */ static u8 ite_get_carrier_freq_bits(unsignedint freq)
{ if (ite_is_high_carrier_freq(freq)) { if (freq < 425000) return ITE_CFQ_400;
elseif (freq < 465000) return ITE_CFQ_450;
elseif (freq < 490000) return ITE_CFQ_480;
else return ITE_CFQ_500;
} else { /* trim to limits */ if (freq < ITE_LCF_MIN_CARRIER_FREQ)
freq = ITE_LCF_MIN_CARRIER_FREQ; if (freq > ITE_LCF_MAX_CARRIER_FREQ)
freq = ITE_LCF_MAX_CARRIER_FREQ;
/* convert to kHz and subtract the base freq */
freq = DIV_ROUND_CLOSEST(freq - ITE_LCF_MIN_CARRIER_FREQ, 1000);
return (u8) freq;
}
}
/* get the bits required to program the pulse with in TXMPW */ static u8 ite_get_pulse_width_bits(unsignedint freq, int duty_cycle)
{ unsignedlong period_ns, on_ns;
/* sanitize freq into range */ if (freq < ITE_LCF_MIN_CARRIER_FREQ)
freq = ITE_LCF_MIN_CARRIER_FREQ; if (freq > ITE_HCF_MAX_CARRIER_FREQ)
freq = ITE_HCF_MAX_CARRIER_FREQ;
/* decode raw bytes as received by the hardware, and push them to the ir-core
* layer */ staticvoid ite_decode_bytes(struct ite_dev *dev, const u8 * data, int
length)
{ unsignedlong *ldata; unsignedint next_one, next_zero, size; struct ir_raw_event ev = {};
/* set all the rx/tx carrier parameters; this must be called with the device
* spinlock held */ staticvoid ite_set_carrier_params(struct ite_dev *dev)
{ unsignedint freq, low_freq, high_freq; int allowance; bool use_demodulator; bool for_tx = dev->transmitting;
if (for_tx) { /* we don't need no stinking calculations */
freq = dev->tx_carrier_freq;
allowance = ITE_RXDCR_DEFAULT;
use_demodulator = false;
} else {
low_freq = dev->rx_low_carrier_freq;
high_freq = dev->rx_high_carrier_freq;
if (allowance > ITE_RXDCR_MAX)
allowance = ITE_RXDCR_MAX;
use_demodulator = true;
}
}
/* set the carrier parameters in a device-dependent way */
dev->params->set_carrier_params(dev, ite_is_high_carrier_freq(freq),
use_demodulator, ite_get_carrier_freq_bits(freq), allowance,
ite_get_pulse_width_bits(freq, dev->tx_duty_cycle));
}
/* interrupt service routine for incoming and outgoing CIR data */ static irqreturn_t ite_cir_isr(int irq, void *data)
{ struct ite_dev *dev = data;
irqreturn_t ret = IRQ_RETVAL(IRQ_NONE);
u8 rx_buf[ITE_RX_FIFO_LEN]; int rx_bytes; int iflags;
/* grab the spinlock */
spin_lock(&dev->lock);
/* read the interrupt flags */
iflags = dev->params->get_irq_causes(dev);
/* Check for RX overflow */ if (iflags & ITE_IRQ_RX_FIFO_OVERRUN) {
dev_warn(&dev->rdev->dev, "receive overflow\n");
ir_raw_event_overflow(dev->rdev);
}
/* check for the receive interrupt */ if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) { /* read the FIFO bytes */
rx_bytes = dev->params->get_rx_bytes(dev, rx_buf,
ITE_RX_FIFO_LEN);
if (rx_bytes > 0) { /* drop the spinlock, since the ir-core layer * may call us back again through
* ite_s_idle() */
spin_unlock(&dev->lock);
/* decode the data we've just received */
ite_decode_bytes(dev, rx_buf, rx_bytes);
/* reacquire the spinlock */
spin_lock(&dev->lock);
/* mark the interrupt as serviced */
ret = IRQ_RETVAL(IRQ_HANDLED);
}
} elseif (iflags & ITE_IRQ_TX_FIFO) { /* FIFO space available interrupt */
dev_dbg(&dev->rdev->dev, "interrupt TX FIFO\n");
/* wake any sleeping transmitter */
wake_up_interruptible(&dev->tx_queue);
/* mark the interrupt as serviced */
ret = IRQ_RETVAL(IRQ_HANDLED);
}
/* drop the spinlock */
spin_unlock(&dev->lock);
return ret;
}
/* set the rx carrier freq range, guess it's in Hz... */ staticint ite_set_rx_carrier_range(struct rc_dev *rcdev, u32 carrier_low, u32
carrier_high)
{ unsignedlong flags; struct ite_dev *dev = rcdev->priv;
/* 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 */ staticint ite_tx_ir(struct rc_dev *rcdev, unsigned *txbuf, unsigned n)
{ unsignedlong 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;
/* clear the array just in case */
memset(last_sent, 0, sizeof(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 * 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) { /* transmit the next sample */
is_pulse = !is_pulse;
remaining_us = *(txbuf++);
n--;
/* repeat while the pulse is non-zero length */ while (remaining_us > 0) { 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);
if (enable) {
spin_lock_irqsave(&dev->lock, flags);
dev->params->idle_rx(dev);
spin_unlock_irqrestore(&dev->lock, flags);
}
}
/* IT8712F HW-specific functions */
/* retrieve a bitmask of the current causes for a pending interrupt; this may * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
* */ staticint it87_get_irq_causes(struct ite_dev *dev)
{
u8 iflags; int ret = 0;
switch (iflags) { case IT87_II_RXDS:
ret = ITE_IRQ_RX_FIFO; break; case IT87_II_RXFO:
ret = ITE_IRQ_RX_FIFO_OVERRUN; break; case IT87_II_TXLDL:
ret = ITE_IRQ_TX_FIFO; break;
}
return ret;
}
/* set the carrier parameters; to be called with the spinlock held */ staticvoid it87_set_carrier_params(struct ite_dev *dev, bool high_freq, bool use_demodulator,
u8 carrier_freq_bits, u8 allowance_bits,
u8 pulse_width_bits)
{
u8 val;
/* program the RCR register */
val = inb(dev->cir_addr + IT87_RCR)
& ~(IT87_HCFS | IT87_RXEND | IT87_RXDCR);
if (high_freq)
val |= IT87_HCFS;
if (use_demodulator)
val |= IT87_RXEND;
val |= allowance_bits;
outb(val, dev->cir_addr + IT87_RCR);
/* program the TCR2 register */
outb((carrier_freq_bits << IT87_CFQ_SHIFT) | pulse_width_bits,
dev->cir_addr + IT87_TCR2);
}
/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
* held */ staticint it87_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
{ int fifo, read = 0;
/* read how many bytes are still in the FIFO */
fifo = inb(dev->cir_addr + IT87_RSR) & IT87_RXFBC;
/* return how many bytes are still in the FIFO; this will be called * with the device spinlock NOT HELD while waiting for the TX FIFO to get
* empty; let's expect this won't be a problem */ staticint it87_get_tx_used_slots(struct ite_dev *dev)
{ return inb(dev->cir_addr + IT87_TSR) & IT87_TXFBC;
}
/* put a byte to the TX fifo; this should be called with the spinlock held */ staticvoid it87_put_tx_byte(struct ite_dev *dev, u8 value)
{
outb(value, dev->cir_addr + IT87_DR);
}
/* idle the receiver so that we won't receive samples until another
pulse is detected; this must be called with the device spinlock held */ staticvoid it87_idle_rx(struct ite_dev *dev)
{ /* disable streaming by clearing RXACT writing it as 1 */
outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXACT,
dev->cir_addr + IT87_RCR);
/* disable the receiver; this must be called with the device spinlock held */ staticvoid it87_disable_rx(struct ite_dev *dev)
{ /* disable the receiver interrupts */
outb(inb(dev->cir_addr + IT87_IER) & ~(IT87_RDAIE | IT87_RFOIE),
dev->cir_addr + IT87_IER);
/* clear the FIFO and RXACT (actually RXACT should have been cleared
* in the previous outb() call) */
it87_idle_rx(dev);
}
/* enable the receiver; this must be called with the device spinlock held */ staticvoid it87_enable_rx(struct ite_dev *dev)
{ /* enable the receiver by setting RXEN */
outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXEN,
dev->cir_addr + IT87_RCR);
/* just prepare it to idle for the next reception */
it87_idle_rx(dev);
/* enable the receiver interrupts and master enable flag */
outb(inb(dev->cir_addr + IT87_IER) | IT87_RDAIE | IT87_RFOIE | IT87_IEC,
dev->cir_addr + IT87_IER);
}
/* disable the transmitter interrupt; this must be called with the device
* spinlock held */ staticvoid it87_disable_tx_interrupt(struct ite_dev *dev)
{ /* disable the transmitter interrupts */
outb(inb(dev->cir_addr + IT87_IER) & ~IT87_TLDLIE,
dev->cir_addr + IT87_IER);
}
/* enable the transmitter interrupt; this must be called with the device
* spinlock held */ staticvoid it87_enable_tx_interrupt(struct ite_dev *dev)
{ /* enable the transmitter interrupts and master enable flag */
outb(inb(dev->cir_addr + IT87_IER) | IT87_TLDLIE | IT87_IEC,
dev->cir_addr + IT87_IER);
}
/* disable the device; this must be called with the device spinlock held */ staticvoid it87_disable(struct ite_dev *dev)
{ /* clear out all interrupt enable flags */
outb(inb(dev->cir_addr + IT87_IER) &
~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE),
dev->cir_addr + IT87_IER);
/* initialize the hardware */ staticvoid it87_init_hardware(struct ite_dev *dev)
{ /* 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);
/* 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);
}
/* IT8512F on ITE8708 HW-specific functions */
/* retrieve a bitmask of the current causes for a pending interrupt; this may * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
* */ staticint it8708_get_irq_causes(struct ite_dev *dev)
{
u8 iflags; int ret = 0;
if (iflags & IT85_TLDLI)
ret |= ITE_IRQ_TX_FIFO; if (iflags & IT85_RDAI)
ret |= ITE_IRQ_RX_FIFO; if (iflags & IT85_RFOI)
ret |= ITE_IRQ_RX_FIFO_OVERRUN;
return ret;
}
/* set the carrier parameters; to be called with the spinlock held */ staticvoid it8708_set_carrier_params(struct ite_dev *dev, bool high_freq, bool use_demodulator,
u8 carrier_freq_bits, u8 allowance_bits,
u8 pulse_width_bits)
{
u8 val;
/* program the C0CFR register, with HRAE=1 */
outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE,
dev->cir_addr + IT8708_BANKSEL);
/* program the C0RCR register */
val = inb(dev->cir_addr + IT8708_C0RCR)
& ~(IT85_RXEND | IT85_RXDCR);
if (use_demodulator)
val |= IT85_RXEND;
val |= allowance_bits;
outb(val, dev->cir_addr + IT8708_C0RCR);
/* program the C0TCR register */
val = inb(dev->cir_addr + IT8708_C0TCR) & ~IT85_TXMPW;
val |= pulse_width_bits;
outb(val, dev->cir_addr + IT8708_C0TCR);
}
/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
* held */ staticint it8708_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
{ int fifo, read = 0;
/* read how many bytes are still in the FIFO */
fifo = inb(dev->cir_addr + IT8708_C0RFSR) & IT85_RXFBC;
/* return how many bytes are still in the FIFO; this will be called * with the device spinlock NOT HELD while waiting for the TX FIFO to get
* empty; let's expect this won't be a problem */ staticint it8708_get_tx_used_slots(struct ite_dev *dev)
{ return inb(dev->cir_addr + IT8708_C0TFSR) & IT85_TXFBC;
}
/* put a byte to the TX fifo; this should be called with the spinlock held */ staticvoid it8708_put_tx_byte(struct ite_dev *dev, u8 value)
{
outb(value, dev->cir_addr + IT8708_C0DR);
}
/* idle the receiver so that we won't receive samples until another
pulse is detected; this must be called with the device spinlock held */ staticvoid it8708_idle_rx(struct ite_dev *dev)
{ /* disable streaming by clearing RXACT writing it as 1 */
outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXACT,
dev->cir_addr + IT8708_C0RCR);
/* disable the receiver; this must be called with the device spinlock held */ staticvoid it8708_disable_rx(struct ite_dev *dev)
{ /* disable the receiver interrupts */
outb(inb(dev->cir_addr + IT8708_C0IER) &
~(IT85_RDAIE | IT85_RFOIE),
dev->cir_addr + IT8708_C0IER);
/* clear the FIFO and RXACT (actually RXACT should have been cleared
* in the previous outb() call) */
it8708_idle_rx(dev);
}
/* enable the receiver; this must be called with the device spinlock held */ staticvoid it8708_enable_rx(struct ite_dev *dev)
{ /* enable the receiver by setting RXEN */
outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXEN,
dev->cir_addr + IT8708_C0RCR);
/* just prepare it to idle for the next reception */
it8708_idle_rx(dev);
/* enable the receiver interrupts and master enable flag */
outb(inb(dev->cir_addr + IT8708_C0IER)
|IT85_RDAIE | IT85_RFOIE | IT85_IEC,
dev->cir_addr + IT8708_C0IER);
}
/* disable the transmitter interrupt; this must be called with the device
* spinlock held */ staticvoid it8708_disable_tx_interrupt(struct ite_dev *dev)
{ /* disable the transmitter interrupts */
outb(inb(dev->cir_addr + IT8708_C0IER) & ~IT85_TLDLIE,
dev->cir_addr + IT8708_C0IER);
}
/* enable the transmitter interrupt; this must be called with the device
* spinlock held */ staticvoid it8708_enable_tx_interrupt(struct ite_dev *dev)
{ /* enable the transmitter interrupts and master enable flag */
outb(inb(dev->cir_addr + IT8708_C0IER)
|IT85_TLDLIE | IT85_IEC,
dev->cir_addr + IT8708_C0IER);
}
/* disable the device; this must be called with the device spinlock held */ staticvoid it8708_disable(struct ite_dev *dev)
{ /* clear out all interrupt enable flags */
outb(inb(dev->cir_addr + IT8708_C0IER) &
~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
dev->cir_addr + IT8708_C0IER);
/* disable the receiver */
it8708_disable_rx(dev);
/* program the carrier parameters */
ite_set_carrier_params(dev);
}
/* IT8512F on ITE8709 HW-specific functions */
/* read a byte from the SRAM module */ staticinline u8 it8709_rm(struct ite_dev *dev, int index)
{
outb(index, dev->cir_addr + IT8709_RAM_IDX); return inb(dev->cir_addr + IT8709_RAM_VAL);
}
/* write a byte to the SRAM module */ staticinlinevoid it8709_wm(struct ite_dev *dev, u8 val, int index)
{
outb(index, dev->cir_addr + IT8709_RAM_IDX);
outb(val, dev->cir_addr + IT8709_RAM_VAL);
}
staticvoid it8709_wait(struct ite_dev *dev)
{ int i = 0; /* * loop until device tells it's ready to continue * iterations count is usually ~750 but can sometimes achieve 13000
*/ for (i = 0; i < 15000; i++) {
udelay(2); if (it8709_rm(dev, IT8709_MODE) == IT8709_IDLE) break;
}
}
/* read the value of a CIR register */ static u8 it8709_rr(struct ite_dev *dev, int index)
{ /* just wait in case the previous access was a write */
it8709_wait(dev);
it8709_wm(dev, index, IT8709_REG_IDX);
it8709_wm(dev, IT8709_READ, IT8709_MODE);
/* wait for the read data to be available */
it8709_wait(dev);
/* return the read value */ return it8709_rm(dev, IT8709_REG_VAL);
}
/* write the value of a CIR register */ staticvoid it8709_wr(struct ite_dev *dev, u8 val, int index)
{ /* we wait before writing, and not afterwards, since this allows us to
* pipeline the host CPU with the microcontroller */
it8709_wait(dev);
it8709_wm(dev, val, IT8709_REG_VAL);
it8709_wm(dev, index, IT8709_REG_IDX);
it8709_wm(dev, IT8709_WRITE, IT8709_MODE);
}
/* retrieve a bitmask of the current causes for a pending interrupt; this may * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
* */ staticint it8709_get_irq_causes(struct ite_dev *dev)
{
u8 iflags; int ret = 0;
/* read the interrupt flags */
iflags = it8709_rm(dev, IT8709_IIR);
if (iflags & IT85_TLDLI)
ret |= ITE_IRQ_TX_FIFO; if (iflags & IT85_RDAI)
ret |= ITE_IRQ_RX_FIFO; if (iflags & IT85_RFOI)
ret |= ITE_IRQ_RX_FIFO_OVERRUN;
return ret;
}
/* set the carrier parameters; to be called with the spinlock held */ staticvoid it8709_set_carrier_params(struct ite_dev *dev, bool high_freq, bool use_demodulator,
u8 carrier_freq_bits, u8 allowance_bits,
u8 pulse_width_bits)
{
u8 val;
val = (it8709_rr(dev, IT85_C0CFR)
&~(IT85_HCFS | IT85_CFQ)) |
carrier_freq_bits;
if (high_freq)
val |= IT85_HCFS;
it8709_wr(dev, val, IT85_C0CFR);
/* program the C0RCR register */
val = it8709_rr(dev, IT85_C0RCR)
& ~(IT85_RXEND | IT85_RXDCR);
if (use_demodulator)
val |= IT85_RXEND;
val |= allowance_bits;
it8709_wr(dev, val, IT85_C0RCR);
/* program the C0TCR register */
val = it8709_rr(dev, IT85_C0TCR) & ~IT85_TXMPW;
val |= pulse_width_bits;
it8709_wr(dev, val, IT85_C0TCR);
}
/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
* held */ staticint it8709_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
{ int fifo, read = 0;
/* read how many bytes are still in the FIFO */
fifo = it8709_rm(dev, IT8709_RFSR) & IT85_RXFBC;
/* 'clear' the FIFO by setting the writing index to 0; this is * completely bound to be racy, but we can't help it, since it's a
* limitation of the protocol */
it8709_wm(dev, 0, IT8709_RFSR);
return read;
}
/* return how many bytes are still in the FIFO; this will be called * with the device spinlock NOT HELD while waiting for the TX FIFO to get
* empty; let's expect this won't be a problem */ staticint it8709_get_tx_used_slots(struct ite_dev *dev)
{ return it8709_rr(dev, IT85_C0TFSR) & IT85_TXFBC;
}
/* put a byte to the TX fifo; this should be called with the spinlock held */ staticvoid it8709_put_tx_byte(struct ite_dev *dev, u8 value)
{
it8709_wr(dev, value, IT85_C0DR);
}
/* idle the receiver so that we won't receive samples until another
pulse is detected; this must be called with the device spinlock held */ staticvoid it8709_idle_rx(struct ite_dev *dev)
{ /* disable streaming by clearing RXACT writing it as 1 */
it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXACT,
IT85_C0RCR);
/* disable the receiver; this must be called with the device spinlock held */ staticvoid it8709_disable_rx(struct ite_dev *dev)
{ /* disable the receiver interrupts */
it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
~(IT85_RDAIE | IT85_RFOIE),
IT85_C0IER);
/* clear the FIFO and RXACT (actually RXACT should have been cleared
* in the previous it8709_wr(dev, ) call) */
it8709_idle_rx(dev);
}
/* enable the receiver; this must be called with the device spinlock held */ staticvoid it8709_enable_rx(struct ite_dev *dev)
{ /* enable the receiver by setting RXEN */
it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXEN,
IT85_C0RCR);
/* just prepare it to idle for the next reception */
it8709_idle_rx(dev);
/* enable the receiver interrupts and master enable flag */
it8709_wr(dev, it8709_rr(dev, IT85_C0IER)
|IT85_RDAIE | IT85_RFOIE | IT85_IEC,
IT85_C0IER);
}
/* disable the transmitter interrupt; this must be called with the device
* spinlock held */ staticvoid it8709_disable_tx_interrupt(struct ite_dev *dev)
{ /* disable the transmitter interrupts */
it8709_wr(dev, it8709_rr(dev, IT85_C0IER) & ~IT85_TLDLIE,
IT85_C0IER);
}
/* enable the transmitter interrupt; this must be called with the device
* spinlock held */ staticvoid it8709_enable_tx_interrupt(struct ite_dev *dev)
{ /* enable the transmitter interrupts and master enable flag */
it8709_wr(dev, it8709_rr(dev, IT85_C0IER)
|IT85_TLDLIE | IT85_IEC,
IT85_C0IER);
}
/* disable the device; this must be called with the device spinlock held */ staticvoid it8709_disable(struct ite_dev *dev)
{ /* clear out all interrupt enable flags */
it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
IT85_C0IER);
/* disable the receiver */
it8709_disable_rx(dev);
/* program the carrier parameters */
ite_set_carrier_params(dev);
}
/* generic hardware setup/teardown code */
/* activate the device for use */ staticint ite_open(struct rc_dev *rcdev)
{ struct ite_dev *dev = rcdev->priv; unsignedlong flags;
spin_lock_irqsave(&dev->lock, flags);
/* enable the receiver */
dev->params->enable_rx(dev);
spin_unlock_irqrestore(&dev->lock, flags);
return 0;
}
/* deactivate the device for use */ staticvoid ite_close(struct rc_dev *rcdev)
{ struct ite_dev *dev = rcdev->priv; unsignedlong flags;
spin_lock_irqsave(&dev->lock, flags);
/* wait for any transmission to end */
spin_unlock_irqrestore(&dev->lock, flags);
wait_event_interruptible(dev->tx_ended, !dev->transmitting);
spin_lock_irqsave(&dev->lock, flags);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.