The patch titled Fixes for the Winbond WPCD376I driver has been added to the -mm tree. Its filename is input-add-a-driver-for-the-winbond-wpcd376i-consumer-ir-hardware-fixes.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** See http://userweb.kernel.org/~akpm/stuff/added-to-mm.txt to find out what to do about this The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/ ------------------------------------------------------ Subject: Fixes for the Winbond WPCD376I driver From: David Härdeman <david@xxxxxxxxxxx> Adds a couple of fixes for the IR RX handling in the drivers/input/misc/winbond-cir.c driver. Most importantly, the hardware forces a FIFO RX/TX buffer size of 16 even though this isn't documented in the specs (meaning that an interrupt is generated when 8 bytes are loaded, not when 16 bytes are loaded). Second, a loop was using the wrong parameter. Third, it makes more sense to disable RX before draining the RX buffer rather than the other way around. This patch applies on top of the patches already in the -mm tree. Signed-off-by: David Härdeman <david@xxxxxxxxxxx> Cc: Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> Cc: Dmitry Torokhov <dtor@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- drivers/input/misc/winbond-cir.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff -puN drivers/input/misc/winbond-cir.c~input-add-a-driver-for-the-winbond-wpcd376i-consumer-ir-hardware-fixes drivers/input/misc/winbond-cir.c --- a/drivers/input/misc/winbond-cir.c~input-add-a-driver-for-the-winbond-wpcd376i-consumer-ir-hardware-fixes +++ a/drivers/input/misc/winbond-cir.c @@ -941,7 +941,7 @@ wbcir_irq_handler(int irqno, void *cooki struct device *dev = &device->dev; u8 status; unsigned long flags; - u8 irdata[16]; + u8 irdata[8]; int i; unsigned int hw; @@ -962,11 +962,10 @@ wbcir_irq_handler(int irqno, void *cooki if (!(status & WBCIR_IRQ_RX)) goto out; - /* Since RXHDLEV is set, at least 16 bytes are in the FIFO */ + /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8); - insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[8], 8); - for (i = 0; i < sizeof(data); i++) { + for (i = 0; i < sizeof(irdata); i++) { hw = hweight8(irdata[i]); if (hw > 4) add_irdata_bit(data, 0); @@ -980,13 +979,13 @@ wbcir_irq_handler(int irqno, void *cooki } if (data->idle_count > WBCIR_MAX_IDLE_BYTES) { - /* Drain the FIFO */ + /* Set RXINACTIVE... */ + outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR); + + /* ...and drain the FIFO */ while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) inb(data->sbase + WBCIR_REG_SP3_RXDATA); - /* And set RXINACTIVE */ - outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR); - dev_dbg(dev, "IRDATA:\n"); for (i = 0; i < data->irdata_count; i += BITS_PER_LONG) dev_dbg(dev, "0x%08lX\n", data->irdata[i/BITS_PER_LONG]); @@ -1438,10 +1437,13 @@ wbcir_probe(struct pnp_dev *device, cons * * The ECIR registers include a flag to change the * 24Mhz clock freq to 48Mhz. + * + * It's not documented in the specs, but fifo levels + * other than 16 seem to be unsupported. */ - /* prescaler 1.0, tx/rx fifo lvl 32 */ - outb(0x35, data->sbase + WBCIR_REG_SP3_EXCR2); + /* prescaler 1.0, tx/rx fifo lvl 16 */ + outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); /* Set baud divisor to generate one byte per bit/cell */ switch (protocol) { @@ -1490,7 +1492,7 @@ wbcir_probe(struct pnp_dev *device, cons else outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); - /* Set FIFO thresholds (RX = 16, TX = 7), reset RX/TX */ + /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ wbcir_select_bank(data, WBCIR_BANK_0); outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); @@ -1498,7 +1500,6 @@ wbcir_probe(struct pnp_dev *device, cons outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); /* Enable interrupts */ - wbcir_select_bank(data, WBCIR_BANK_0); outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); return 0; _ Patches currently in -mm which might be from david@xxxxxxxxxxx are acpi-reintroduce-acpi_device_ops-shutdown-method.patch input-add-a-shutdown-method-to-pnp-drivers.patch input-add-a-driver-for-the-winbond-wpcd376i-consumer-ir-hardware.patch input-add-a-driver-for-the-winbond-wpcd376i-consumer-ir-hardware-fixes.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html