#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/bitops.h>
sample_period = dev->params.sample_period;
ldata = (unsigned long *)data;
size = length << 3;
- next_one = generic_find_next_le_bit(ldata, size, 0);
+ next_one = find_next_bit_le(ldata, size, 0);
if (next_one > 0) {
ev.pulse = true;
ev.duration =
}
while (next_one < size) {
- next_zero = generic_find_next_zero_le_bit(ldata, size, next_one + 1);
+ 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 =
- generic_find_next_le_bit(ldata,
+ find_next_bit_le(ldata,
size,
next_zero + 1);
ev.pulse = true;
/* 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, int *txbuf, u32 n)
+static int ite_tx_ir(struct rc_dev *rcdev, unsigned *txbuf, unsigned n)
{
unsigned long flags;
struct ite_dev *dev = rcdev->priv;
/* clear the array just in case */
memset(last_sent, 0, ARRAY_SIZE(last_sent));
- /* n comes in bytes; convert to ints */
- n /= sizeof(int);
-
spin_lock_irqsave(&dev->lock, flags);
/* let everybody know we're now transmitting */
else
val |= ITE_TX_SPACE;
- /* if we get to 0 available, read again, just in case
- * some other slot got freed */
+ /*
+ * 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);
ite_dbg("%s called", __func__);
/* clear out all interrupt enable flags */
- it8709_wr(dev,
- it8709_rr(dev,
- IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
- IT85_RDAIE |
- IT85_TLDLIE), IT85_C0IER);
+ 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);
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);
+ 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);
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);
+ 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);
+ 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);
+ 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);
{ /* 0: ITE8704 */
.model = "ITE8704 CIR transceiver",
.io_region_size = IT87_IOREG_LENGTH,
+ .io_rsrc_no = 0,
.hw_tx_capable = true,
.sample_period = (u32) (1000000000ULL / 115200),
.tx_carrier_freq = 38000,
{ /* 1: ITE8713 */
.model = "ITE8713 CIR transceiver",
.io_region_size = IT87_IOREG_LENGTH,
+ .io_rsrc_no = 0,
.hw_tx_capable = true,
.sample_period = (u32) (1000000000ULL / 115200),
.tx_carrier_freq = 38000,
{ /* 2: ITE8708 */
.model = "ITE8708 CIR transceiver",
.io_region_size = IT8708_IOREG_LENGTH,
+ .io_rsrc_no = 0,
.hw_tx_capable = true,
.sample_period = (u32) (1000000000ULL / 115200),
.tx_carrier_freq = 38000,
{ /* 3: ITE8709 */
.model = "ITE8709 CIR transceiver",
.io_region_size = IT8709_IOREG_LENGTH,
+ .io_rsrc_no = 2,
.hw_tx_capable = true,
.sample_period = (u32) (1000000000ULL / 115200),
.tx_carrier_freq = 38000,
struct rc_dev *rdev = NULL;
int ret = -ENOMEM;
int model_no;
+ int io_rsrc_no;
ite_dbg("%s called", __func__);
/* get the description for the device */
dev_desc = &ite_dev_descs[model_no];
+ io_rsrc_no = dev_desc->io_rsrc_no;
/* validate pnp resources */
- if (!pnp_port_valid(pdev, 0) ||
- pnp_port_len(pdev, 0) != dev_desc->io_region_size) {
+ if (!pnp_port_valid(pdev, io_rsrc_no) ||
+ pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) {
dev_err(&pdev->dev, "IR PNP Port not valid!\n");
goto failure;
}
}
/* store resource values */
- itdev->cir_addr = pnp_port_start(pdev, 0);
- itdev->cir_irq =pnp_irq(pdev, 0);
+ itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no);
+ itdev->cir_irq = pnp_irq(pdev, 0);
/* initialize spinlocks */
spin_lock_init(&itdev->lock);
/* initialize raw event */
init_ir_raw_event(&itdev->rawir);
- ret = -EBUSY;
- /* now claim resources */
- if (!request_region(itdev->cir_addr,
- dev_desc->io_region_size, ITE_DRIVER_NAME))
- goto failure;
-
- if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
- ITE_DRIVER_NAME, (void *)itdev))
- goto failure;
-
/* set driver data into the pnp device */
pnp_set_drvdata(pdev, itdev);
itdev->pdev = pdev;
rdev->driver_name = ITE_DRIVER_NAME;
rdev->map_name = RC_MAP_RC6_MCE;
+ ret = -EBUSY;
+ /* now claim resources */
+ if (!request_region(itdev->cir_addr,
+ dev_desc->io_region_size, ITE_DRIVER_NAME))
+ goto failure;
+
+ if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
+ ITE_DRIVER_NAME, (void *)itdev))
+ goto failure;
+
ret = rc_register_device(rdev);
if (ret)
goto failure;
ite_dbg("%s called", __func__);
+ /* wait for any transmission to end */
+ wait_event_interruptible(dev->tx_ended, !dev->transmitting);
+
spin_lock_irqsave(&dev->lock, flags);
/* disable all interrupts */
spin_lock_irqsave(&dev->lock, flags);
- if (dev->transmitting) {
- /* wake up the transmitter */
- wake_up_interruptible(&dev->tx_queue);
- } else {
- /* enable the receiver */
- dev->params.enable_rx(dev);
- }
+ /* reinitialize hardware config registers */
+ dev->params.init_hardware(dev);
+ /* enable the receiver */
+ dev->params.enable_rx(dev);
spin_unlock_irqrestore(&dev->lock, flags);