All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] Series short description
@ 2009-01-15 13:29 Alan Cox
  0 siblings, 0 replies; 30+ messages in thread
From: Alan Cox @ 2009-01-15 13:29 UTC (permalink / raw)
  To: torvalds, linux-kernel

Assorted small tty fixes, mostly for the HSO driver which appears not to have
been my finest conversion.

---

Alan Cox (2):
      tty: Fix a kref leak in the HSO driver on re-open
      tty: Fix race in the flush for some ldiscs

Daniel Gagnon (1):
      serial: Add SupraExpress 336i PnP Voice Modem

Denis Joseph Barrow (2):
      hso serial throttled tty kref fix.
      tty: Fix double grabbing of a spinlock

Jim Paris (1):
      ftdi_sio: fix kref leak

Jiri Slaby (1):
      8250_pci: add support for netmos 9835 IBM devices

Mischa Jonker (1):
      When a break signal is detected, the next character should be ignored.


 drivers/char/tty_ioctl.c      |    2 +-
 drivers/net/usb/hso.c         |    8 +++++---
 drivers/serial/8250_pci.c     |    8 ++++++++
 drivers/serial/8250_pnp.c     |    2 ++
 drivers/serial/pnx8xxx_uart.c |   23 ++++++++++++-----------
 drivers/usb/serial/ftdi_sio.c |    2 +-
 6 files changed, 29 insertions(+), 16 deletions(-)

-- 
		Take control of enterprise infrastructure
		   Sign up for starfleet academy today


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/8] Series short description
@ 2009-05-01 16:36 Chuck Lever
  0 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-05-01 16:36 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs

Hi Trond-

In-kernel MNT client changes proposed for 2.6.31.  Comments?

---

Chuck Lever (8):
      NFS: Remove unused XDR decoder functions
      NFS: Update MNT and MNT3 reply decoding functions
      NFS: add XDR decoder for mountd version 3 auth-flavor lists
      NFS: add new file handle decoders to in-kernel mountd client
      NFS: Add separate mountd status code decoders for each mountd version
      NFS: remove unused function in fs/nfs/mount_clnt.c
      NFS: Use xdr_stream-based XDR encoder for MNT's dirpath argument
      NFS: Clean up MNT program definitions


 fs/nfs/internal.h    |    8 +
 fs/nfs/mount_clnt.c  |  354 ++++++++++++++++++++++++++++++++++++++++++++------
 fs/nfs/nfsroot.c     |    5 +
 fs/nfs/super.c       |    2 
 include/linux/nfs.h  |    5 -
 include/linux/nfs2.h |    7 -
 include/linux/nfs3.h |    5 -
 7 files changed, 331 insertions(+), 55 deletions(-)

-- 
Chuck Lever <chuck.lever@oracle.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/8] Series short description
@ 2009-11-26  0:18 ` Tony Lindgren
  0 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2009-11-26  0:18 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: linux-omap

Hi all,

Here are some omap mux updates for review. These
are intended for the v2.6.33 merge window.

Initially this series changes the omap34xx mux
code, I'm planning on adding 3630, 2420, and 2430
code later on.

There are several reasons why we need better mux
code:

- We want to make the mux code more generic and this
  will allow us to use the internal signal names and
  gpio numbers instead of mux register offsets. The
  internal signal names stay the same across omap
  generations for some devices.

- We need to map mux registers to GPIO registers for
  dynamic muxing of the GPIO pins during off-idle.

- We want to be able to override the bootloader mux
  values for the modded boards, such as the Beagle.

- We want to have the mux signals and balls available
  under debugfs for debugging new drivers.

Some of these might eventually work for other archs
too, so let me know if you have any comments on that.

Regards,

Tony

Here are some instructions on how to use:

To see what got muxed during init, edit the kernel
CMDLINE to have debug in it:

# dmesg | grep mux
mux: Setting signal i2c2_scl.i2c2_scl 0x0100 -> 0x0100
mux: Setting signal i2c2_sda.i2c2_sda 0x0100 -> 0x0100
mux: Setting signal i2c3_scl.i2c3_scl 0x0100 -> 0x0100
mux: Setting signal i2c3_sda.i2c3_sda 0x0100 -> 0x0100
mux: Setting signal gpmc_ncs3.gpio54 0x410c -> 0x010c
...

Looks like the gpmc_ncs3.gpio54 muxing in the kernel
has a bug where we should have OMAP_WAKEUP_EN set for
board_smc91x_init for board-rx51? :)

To override bootloader mux settings, edit the kernel CMDLINE:

omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100

Note that this only changes the bootloader settings, not
what might be muxed from the board-*.c files.

With CONFIG_DEBUG_FS set:

# mount -t sysfs sys /sys
# mount -t debugfs debug /sys/kernel/debug

# ls /sys/kernel/debug/omap_mux/i2c
i2c2_scl  i2c2_sda  i2c3_scl  i2c3_sda  i2c4_scl  i2c4_sda

# cat /sys/kernel/debug/omap_mux/i2c2_scl
name: i2c2_scl.i2c2_scl (0x480021be/0x18e = 0x0100), b af15, t NA
mode: OMAP_PIN_INPUT | OMAP_MUX_MODE0
signals: i2c2_scl | NA | NA | NA | gpio_168 | NA | NA | safe_mode

---

Mike Rapoport (1):
      omap2: mux: intoduce omap_mux_{read,write}

Tony Lindgren (7):
      omap: mux: Add new style pin multiplexing code for omap3
      omap: mux: Add new style pin multiplexing data for 34xx
      omap: mux: Add new style init functions to omap3 board-*.c files
      omap: mux: Add debugfs support for new mux code
      omap: Split i2c platform init for mach-omap1 and mach-omap2
      omap: mux: Replace omap_cfg_reg() with new style signal or gpio functions
      omap: mux: Remove old mux code for 34xx


 arch/arm/mach-omap2/Makefile                 |    4 
 arch/arm/mach-omap2/board-3430sdp.c          |   13 
 arch/arm/mach-omap2/board-3630sdp.c          |    3 
 arch/arm/mach-omap2/board-am3517evm.c        |   11 
 arch/arm/mach-omap2/board-cm-t35.c           |   13 
 arch/arm/mach-omap2/board-igep0020.c         |   11 
 arch/arm/mach-omap2/board-ldp.c              |   10 
 arch/arm/mach-omap2/board-omap3beagle.c      |   21 
 arch/arm/mach-omap2/board-omap3evm.c         |   21 
 arch/arm/mach-omap2/board-omap3pandora.c     |   15 
 arch/arm/mach-omap2/board-overo.c            |   14 
 arch/arm/mach-omap2/board-rx51-peripherals.c |    7 
 arch/arm/mach-omap2/board-rx51.c             |   16 
 arch/arm/mach-omap2/board-zoom2.c            |   11 
 arch/arm/mach-omap2/devices.c                |   62 +
 arch/arm/mach-omap2/mux.c                    |  961 ++++++++++------
 arch/arm/mach-omap2/mux.h                    |  150 +++
 arch/arm/mach-omap2/mux34xx.c                | 1558 ++++++++++++++++++++++++++
 arch/arm/mach-omap2/mux34xx.h                |  351 ++++++
 arch/arm/mach-omap2/usb-ehci.c               |  122 +-
 arch/arm/plat-omap/i2c.c                     |   24 
 arch/arm/plat-omap/include/plat/common.h     |    1 
 arch/arm/plat-omap/include/plat/mux.h        |  222 ----
 arch/arm/plat-omap/mux.c                     |    8 
 24 files changed, 2932 insertions(+), 697 deletions(-)
 create mode 100644 arch/arm/mach-omap2/mux.h
 create mode 100644 arch/arm/mach-omap2/mux34xx.c
 create mode 100644 arch/arm/mach-omap2/mux34xx.h

-- 
Signature

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/8] Series short description
@ 2009-11-26  0:18 ` Tony Lindgren
  0 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2009-11-26  0:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

Here are some omap mux updates for review. These
are intended for the v2.6.33 merge window.

Initially this series changes the omap34xx mux
code, I'm planning on adding 3630, 2420, and 2430
code later on.

There are several reasons why we need better mux
code:

- We want to make the mux code more generic and this
  will allow us to use the internal signal names and
  gpio numbers instead of mux register offsets. The
  internal signal names stay the same across omap
  generations for some devices.

- We need to map mux registers to GPIO registers for
  dynamic muxing of the GPIO pins during off-idle.

- We want to be able to override the bootloader mux
  values for the modded boards, such as the Beagle.

- We want to have the mux signals and balls available
  under debugfs for debugging new drivers.

Some of these might eventually work for other archs
too, so let me know if you have any comments on that.

Regards,

Tony

Here are some instructions on how to use:

To see what got muxed during init, edit the kernel
CMDLINE to have debug in it:

# dmesg | grep mux
mux: Setting signal i2c2_scl.i2c2_scl 0x0100 -> 0x0100
mux: Setting signal i2c2_sda.i2c2_sda 0x0100 -> 0x0100
mux: Setting signal i2c3_scl.i2c3_scl 0x0100 -> 0x0100
mux: Setting signal i2c3_sda.i2c3_sda 0x0100 -> 0x0100
mux: Setting signal gpmc_ncs3.gpio54 0x410c -> 0x010c
...

Looks like the gpmc_ncs3.gpio54 muxing in the kernel
has a bug where we should have OMAP_WAKEUP_EN set for
board_smc91x_init for board-rx51? :)

To override bootloader mux settings, edit the kernel CMDLINE:

omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100

Note that this only changes the bootloader settings, not
what might be muxed from the board-*.c files.

With CONFIG_DEBUG_FS set:

# mount -t sysfs sys /sys
# mount -t debugfs debug /sys/kernel/debug

# ls /sys/kernel/debug/omap_mux/i2c
i2c2_scl  i2c2_sda  i2c3_scl  i2c3_sda  i2c4_scl  i2c4_sda

# cat /sys/kernel/debug/omap_mux/i2c2_scl
name: i2c2_scl.i2c2_scl (0x480021be/0x18e = 0x0100), b af15, t NA
mode: OMAP_PIN_INPUT | OMAP_MUX_MODE0
signals: i2c2_scl | NA | NA | NA | gpio_168 | NA | NA | safe_mode

---

Mike Rapoport (1):
      omap2: mux: intoduce omap_mux_{read,write}

Tony Lindgren (7):
      omap: mux: Add new style pin multiplexing code for omap3
      omap: mux: Add new style pin multiplexing data for 34xx
      omap: mux: Add new style init functions to omap3 board-*.c files
      omap: mux: Add debugfs support for new mux code
      omap: Split i2c platform init for mach-omap1 and mach-omap2
      omap: mux: Replace omap_cfg_reg() with new style signal or gpio functions
      omap: mux: Remove old mux code for 34xx


 arch/arm/mach-omap2/Makefile                 |    4 
 arch/arm/mach-omap2/board-3430sdp.c          |   13 
 arch/arm/mach-omap2/board-3630sdp.c          |    3 
 arch/arm/mach-omap2/board-am3517evm.c        |   11 
 arch/arm/mach-omap2/board-cm-t35.c           |   13 
 arch/arm/mach-omap2/board-igep0020.c         |   11 
 arch/arm/mach-omap2/board-ldp.c              |   10 
 arch/arm/mach-omap2/board-omap3beagle.c      |   21 
 arch/arm/mach-omap2/board-omap3evm.c         |   21 
 arch/arm/mach-omap2/board-omap3pandora.c     |   15 
 arch/arm/mach-omap2/board-overo.c            |   14 
 arch/arm/mach-omap2/board-rx51-peripherals.c |    7 
 arch/arm/mach-omap2/board-rx51.c             |   16 
 arch/arm/mach-omap2/board-zoom2.c            |   11 
 arch/arm/mach-omap2/devices.c                |   62 +
 arch/arm/mach-omap2/mux.c                    |  961 ++++++++++------
 arch/arm/mach-omap2/mux.h                    |  150 +++
 arch/arm/mach-omap2/mux34xx.c                | 1558 ++++++++++++++++++++++++++
 arch/arm/mach-omap2/mux34xx.h                |  351 ++++++
 arch/arm/mach-omap2/usb-ehci.c               |  122 +-
 arch/arm/plat-omap/i2c.c                     |   24 
 arch/arm/plat-omap/include/plat/common.h     |    1 
 arch/arm/plat-omap/include/plat/mux.h        |  222 ----
 arch/arm/plat-omap/mux.c                     |    8 
 24 files changed, 2932 insertions(+), 697 deletions(-)
 create mode 100644 arch/arm/mach-omap2/mux.h
 create mode 100644 arch/arm/mach-omap2/mux34xx.c
 create mode 100644 arch/arm/mach-omap2/mux34xx.h

-- 
Signature

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/8] Series short description
  2009-11-26  0:18 ` Tony Lindgren
@ 2009-11-26  6:44   ` Hemanth V
  -1 siblings, 0 replies; 30+ messages in thread
From: Hemanth V @ 2009-11-26  6:44 UTC (permalink / raw)
  To: linux-arm-kernel, Tony Lindgren, linux-omap

----- Original Message ----- 
From: "Tony Lindgren" <tony@atomide.com>
To: <linux-arm-kernel@lists.infradead.org>
Cc: <linux-omap@vger.kernel.org>
Sent: Thursday, November 26, 2009 5:48 AM
Subject: [PATCH 0/8] Series short description


> Hi all,
>
> Here are some omap mux updates for review. These
> are intended for the v2.6.33 merge window.
>
> Initially this series changes the omap34xx mux
> code, I'm planning on adding 3630, 2420, and 2430
> code later on.
>
> There are several reasons why we need better mux
> code:
>
> - We want to make the mux code more generic and this
>  will allow us to use the internal signal names and
>  gpio numbers instead of mux register offsets. The
>  internal signal names stay the same across omap
>  generations for some devices.
>
> - We need to map mux registers to GPIO registers for
>  dynamic muxing of the GPIO pins during off-idle.
>
> - We want to be able to override the bootloader mux
>  values for the modded boards, such as the Beagle.
>
> - We want to have the mux signals and balls available
>  under debugfs for debugging new drivers.

Does it also detect conflicts when two drivers try
to step on each other and overwrite the mux settings of
other. SPI and EHCI was one of the problems I faced.


>
> Some of these might eventually work for other archs
> too, so let me know if you have any comments on that.
>
> Regards,
>
> Tony
>
> Here are some instructions on how to use:
>
> To see what got muxed during init, edit the kernel
> CMDLINE to have debug in it:
>
> # dmesg | grep mux
> mux: Setting signal i2c2_scl.i2c2_scl 0x0100 -> 0x0100
> mux: Setting signal i2c2_sda.i2c2_sda 0x0100 -> 0x0100
> mux: Setting signal i2c3_scl.i2c3_scl 0x0100 -> 0x0100
> mux: Setting signal i2c3_sda.i2c3_sda 0x0100 -> 0x0100
> mux: Setting signal gpmc_ncs3.gpio54 0x410c -> 0x010c
> ...
>
> Looks like the gpmc_ncs3.gpio54 muxing in the kernel
> has a bug where we should have OMAP_WAKEUP_EN set for
> board_smc91x_init for board-rx51? :)
>
> To override bootloader mux settings, edit the kernel CMDLINE:
>
> omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100
>
> Note that this only changes the bootloader settings, not
> what might be muxed from the board-*.c files.
>
> With CONFIG_DEBUG_FS set:
>
> # mount -t sysfs sys /sys
> # mount -t debugfs debug /sys/kernel/debug
>
> # ls /sys/kernel/debug/omap_mux/i2c
> i2c2_scl  i2c2_sda  i2c3_scl  i2c3_sda  i2c4_scl  i2c4_sda
>
> # cat /sys/kernel/debug/omap_mux/i2c2_scl
> name: i2c2_scl.i2c2_scl (0x480021be/0x18e = 0x0100), b af15, t NA
> mode: OMAP_PIN_INPUT | OMAP_MUX_MODE0
> signals: i2c2_scl | NA | NA | NA | gpio_168 | NA | NA | safe_mode
>
> ---
>
> Mike Rapoport (1):
>      omap2: mux: intoduce omap_mux_{read,write}
>
> Tony Lindgren (7):
>      omap: mux: Add new style pin multiplexing code for omap3
>      omap: mux: Add new style pin multiplexing data for 34xx
>      omap: mux: Add new style init functions to omap3 board-*.c files
>      omap: mux: Add debugfs support for new mux code
>      omap: Split i2c platform init for mach-omap1 and mach-omap2
>      omap: mux: Replace omap_cfg_reg() with new style signal or gpio 
> functions
>      omap: mux: Remove old mux code for 34xx
>
>
> arch/arm/mach-omap2/Makefile                 |    4
> arch/arm/mach-omap2/board-3430sdp.c          |   13
> arch/arm/mach-omap2/board-3630sdp.c          |    3
> arch/arm/mach-omap2/board-am3517evm.c        |   11
> arch/arm/mach-omap2/board-cm-t35.c           |   13
> arch/arm/mach-omap2/board-igep0020.c         |   11
> arch/arm/mach-omap2/board-ldp.c              |   10
> arch/arm/mach-omap2/board-omap3beagle.c      |   21
> arch/arm/mach-omap2/board-omap3evm.c         |   21
> arch/arm/mach-omap2/board-omap3pandora.c     |   15
> arch/arm/mach-omap2/board-overo.c            |   14
> arch/arm/mach-omap2/board-rx51-peripherals.c |    7
> arch/arm/mach-omap2/board-rx51.c             |   16
> arch/arm/mach-omap2/board-zoom2.c            |   11
> arch/arm/mach-omap2/devices.c                |   62 +
> arch/arm/mach-omap2/mux.c                    |  961 ++++++++++------
> arch/arm/mach-omap2/mux.h                    |  150 +++
> arch/arm/mach-omap2/mux34xx.c                | 1558 
> ++++++++++++++++++++++++++
> arch/arm/mach-omap2/mux34xx.h                |  351 ++++++
> arch/arm/mach-omap2/usb-ehci.c               |  122 +-
> arch/arm/plat-omap/i2c.c                     |   24
> arch/arm/plat-omap/include/plat/common.h     |    1
> arch/arm/plat-omap/include/plat/mux.h        |  222 ----
> arch/arm/plat-omap/mux.c                     |    8
> 24 files changed, 2932 insertions(+), 697 deletions(-)
> create mode 100644 arch/arm/mach-omap2/mux.h
> create mode 100644 arch/arm/mach-omap2/mux34xx.c
> create mode 100644 arch/arm/mach-omap2/mux34xx.h
>
> -- 
> Signature
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/8] Series short description
@ 2009-11-26  6:44   ` Hemanth V
  0 siblings, 0 replies; 30+ messages in thread
From: Hemanth V @ 2009-11-26  6:44 UTC (permalink / raw)
  To: linux-arm-kernel

----- Original Message ----- 
From: "Tony Lindgren" <tony@atomide.com>
To: <linux-arm-kernel@lists.infradead.org>
Cc: <linux-omap@vger.kernel.org>
Sent: Thursday, November 26, 2009 5:48 AM
Subject: [PATCH 0/8] Series short description


> Hi all,
>
> Here are some omap mux updates for review. These
> are intended for the v2.6.33 merge window.
>
> Initially this series changes the omap34xx mux
> code, I'm planning on adding 3630, 2420, and 2430
> code later on.
>
> There are several reasons why we need better mux
> code:
>
> - We want to make the mux code more generic and this
>  will allow us to use the internal signal names and
>  gpio numbers instead of mux register offsets. The
>  internal signal names stay the same across omap
>  generations for some devices.
>
> - We need to map mux registers to GPIO registers for
>  dynamic muxing of the GPIO pins during off-idle.
>
> - We want to be able to override the bootloader mux
>  values for the modded boards, such as the Beagle.
>
> - We want to have the mux signals and balls available
>  under debugfs for debugging new drivers.

Does it also detect conflicts when two drivers try
to step on each other and overwrite the mux settings of
other. SPI and EHCI was one of the problems I faced.


>
> Some of these might eventually work for other archs
> too, so let me know if you have any comments on that.
>
> Regards,
>
> Tony
>
> Here are some instructions on how to use:
>
> To see what got muxed during init, edit the kernel
> CMDLINE to have debug in it:
>
> # dmesg | grep mux
> mux: Setting signal i2c2_scl.i2c2_scl 0x0100 -> 0x0100
> mux: Setting signal i2c2_sda.i2c2_sda 0x0100 -> 0x0100
> mux: Setting signal i2c3_scl.i2c3_scl 0x0100 -> 0x0100
> mux: Setting signal i2c3_sda.i2c3_sda 0x0100 -> 0x0100
> mux: Setting signal gpmc_ncs3.gpio54 0x410c -> 0x010c
> ...
>
> Looks like the gpmc_ncs3.gpio54 muxing in the kernel
> has a bug where we should have OMAP_WAKEUP_EN set for
> board_smc91x_init for board-rx51? :)
>
> To override bootloader mux settings, edit the kernel CMDLINE:
>
> omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100
>
> Note that this only changes the bootloader settings, not
> what might be muxed from the board-*.c files.
>
> With CONFIG_DEBUG_FS set:
>
> # mount -t sysfs sys /sys
> # mount -t debugfs debug /sys/kernel/debug
>
> # ls /sys/kernel/debug/omap_mux/i2c
> i2c2_scl  i2c2_sda  i2c3_scl  i2c3_sda  i2c4_scl  i2c4_sda
>
> # cat /sys/kernel/debug/omap_mux/i2c2_scl
> name: i2c2_scl.i2c2_scl (0x480021be/0x18e = 0x0100), b af15, t NA
> mode: OMAP_PIN_INPUT | OMAP_MUX_MODE0
> signals: i2c2_scl | NA | NA | NA | gpio_168 | NA | NA | safe_mode
>
> ---
>
> Mike Rapoport (1):
>      omap2: mux: intoduce omap_mux_{read,write}
>
> Tony Lindgren (7):
>      omap: mux: Add new style pin multiplexing code for omap3
>      omap: mux: Add new style pin multiplexing data for 34xx
>      omap: mux: Add new style init functions to omap3 board-*.c files
>      omap: mux: Add debugfs support for new mux code
>      omap: Split i2c platform init for mach-omap1 and mach-omap2
>      omap: mux: Replace omap_cfg_reg() with new style signal or gpio 
> functions
>      omap: mux: Remove old mux code for 34xx
>
>
> arch/arm/mach-omap2/Makefile                 |    4
> arch/arm/mach-omap2/board-3430sdp.c          |   13
> arch/arm/mach-omap2/board-3630sdp.c          |    3
> arch/arm/mach-omap2/board-am3517evm.c        |   11
> arch/arm/mach-omap2/board-cm-t35.c           |   13
> arch/arm/mach-omap2/board-igep0020.c         |   11
> arch/arm/mach-omap2/board-ldp.c              |   10
> arch/arm/mach-omap2/board-omap3beagle.c      |   21
> arch/arm/mach-omap2/board-omap3evm.c         |   21
> arch/arm/mach-omap2/board-omap3pandora.c     |   15
> arch/arm/mach-omap2/board-overo.c            |   14
> arch/arm/mach-omap2/board-rx51-peripherals.c |    7
> arch/arm/mach-omap2/board-rx51.c             |   16
> arch/arm/mach-omap2/board-zoom2.c            |   11
> arch/arm/mach-omap2/devices.c                |   62 +
> arch/arm/mach-omap2/mux.c                    |  961 ++++++++++------
> arch/arm/mach-omap2/mux.h                    |  150 +++
> arch/arm/mach-omap2/mux34xx.c                | 1558 
> ++++++++++++++++++++++++++
> arch/arm/mach-omap2/mux34xx.h                |  351 ++++++
> arch/arm/mach-omap2/usb-ehci.c               |  122 +-
> arch/arm/plat-omap/i2c.c                     |   24
> arch/arm/plat-omap/include/plat/common.h     |    1
> arch/arm/plat-omap/include/plat/mux.h        |  222 ----
> arch/arm/plat-omap/mux.c                     |    8
> 24 files changed, 2932 insertions(+), 697 deletions(-)
> create mode 100644 arch/arm/mach-omap2/mux.h
> create mode 100644 arch/arm/mach-omap2/mux34xx.c
> create mode 100644 arch/arm/mach-omap2/mux34xx.h
>
> -- 
> Signature
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/8] Series short description
  2009-11-26  6:44   ` Hemanth V
@ 2009-11-26  8:27     ` Tony Lindgren
  -1 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2009-11-26  8:27 UTC (permalink / raw)
  To: Hemanth V; +Cc: linux-arm-kernel, linux-omap

* Hemanth V <hemanthv@ti.com> [091125 22:44]:
> ----- Original Message ----- From: "Tony Lindgren"
> <tony@atomide.com>
> To: <linux-arm-kernel@lists.infradead.org>
> Cc: <linux-omap@vger.kernel.org>
> Sent: Thursday, November 26, 2009 5:48 AM
> Subject: [PATCH 0/8] Series short description
> 
> 
> >Hi all,
> >
> >Here are some omap mux updates for review. These
> >are intended for the v2.6.33 merge window.
> >
> >Initially this series changes the omap34xx mux
> >code, I'm planning on adding 3630, 2420, and 2430
> >code later on.
> >
> >There are several reasons why we need better mux
> >code:
> >
> >- We want to make the mux code more generic and this
> > will allow us to use the internal signal names and
> > gpio numbers instead of mux register offsets. The
> > internal signal names stay the same across omap
> > generations for some devices.
> >
> >- We need to map mux registers to GPIO registers for
> > dynamic muxing of the GPIO pins during off-idle.
> >
> >- We want to be able to override the bootloader mux
> > values for the modded boards, such as the Beagle.
> >
> >- We want to have the mux signals and balls available
> > under debugfs for debugging new drivers.
> 
> Does it also detect conflicts when two drivers try
> to step on each other and overwrite the mux settings of
> other. SPI and EHCI was one of the problems I faced.
 
It does not, but that could be added by adding a
usecount to struct omap_mux.

In fact it's already a problem with the cmdline mux
options as that does not prevent other init code from
muxing over the cmdline options.

But then again, just being able to override the
bootloader settings might do the trick for most people
customizing their Beagle boards.

Currently we're not checking the return values for
muxing, so adding a usecount sounds like a follow-up
patch after these changes.

Regards,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/8] Series short description
@ 2009-11-26  8:27     ` Tony Lindgren
  0 siblings, 0 replies; 30+ messages in thread
From: Tony Lindgren @ 2009-11-26  8:27 UTC (permalink / raw)
  To: linux-arm-kernel

* Hemanth V <hemanthv@ti.com> [091125 22:44]:
> ----- Original Message ----- From: "Tony Lindgren"
> <tony@atomide.com>
> To: <linux-arm-kernel@lists.infradead.org>
> Cc: <linux-omap@vger.kernel.org>
> Sent: Thursday, November 26, 2009 5:48 AM
> Subject: [PATCH 0/8] Series short description
> 
> 
> >Hi all,
> >
> >Here are some omap mux updates for review. These
> >are intended for the v2.6.33 merge window.
> >
> >Initially this series changes the omap34xx mux
> >code, I'm planning on adding 3630, 2420, and 2430
> >code later on.
> >
> >There are several reasons why we need better mux
> >code:
> >
> >- We want to make the mux code more generic and this
> > will allow us to use the internal signal names and
> > gpio numbers instead of mux register offsets. The
> > internal signal names stay the same across omap
> > generations for some devices.
> >
> >- We need to map mux registers to GPIO registers for
> > dynamic muxing of the GPIO pins during off-idle.
> >
> >- We want to be able to override the bootloader mux
> > values for the modded boards, such as the Beagle.
> >
> >- We want to have the mux signals and balls available
> > under debugfs for debugging new drivers.
> 
> Does it also detect conflicts when two drivers try
> to step on each other and overwrite the mux settings of
> other. SPI and EHCI was one of the problems I faced.
 
It does not, but that could be added by adding a
usecount to struct omap_mux.

In fact it's already a problem with the cmdline mux
options as that does not prevent other init code from
muxing over the cmdline options.

But then again, just being able to override the
bootloader settings might do the trick for most people
customizing their Beagle boards.

Currently we're not checking the return values for
muxing, so adding a usecount sounds like a follow-up
patch after these changes.

Regards,

Tony

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [PATCH 0/8] Series short description
  2009-11-26  0:18 ` Tony Lindgren
@ 2009-11-29 10:03   ` Shilimkar, Santosh
  -1 siblings, 0 replies; 30+ messages in thread
From: Shilimkar, Santosh @ 2009-11-29 10:03 UTC (permalink / raw)
  To: Tony Lindgren, linux-arm-kernel@lists.infradead.org
  Cc: linux-omap@vger.kernel.org

Tony,
> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> owner@vger.kernel.org] On Behalf Of Tony Lindgren
> Sent: Thursday, November 26, 2009 5:49 AM
> To: linux-arm-kernel@lists.infradead.org
> Cc: linux-omap@vger.kernel.org
> Subject: [PATCH 0/8] Series short description
> 
> Hi all,
> 
> Here are some omap mux updates for review. These
> are intended for the v2.6.33 merge window.
> 
> Initially this series changes the omap34xx mux
> code, I'm planning on adding 3630, 2420, and 2430
> code later on.
> 
> There are several reasons why we need better mux
> code:
> 
> - We want to make the mux code more generic and this
>   will allow us to use the internal signal names and
>   gpio numbers instead of mux register offsets. The
>   internal signal names stay the same across omap
>   generations for some devices.
> 
> - We need to map mux registers to GPIO registers for
>   dynamic muxing of the GPIO pins during off-idle.
> 
> - We want to be able to override the bootloader mux
>   values for the modded boards, such as the Beagle.
> 
> - We want to have the mux signals and balls available
>   under debugfs for debugging new drivers.
> 
> Some of these might eventually work for other archs
> too, so let me know if you have any comments on that.

Thanks for the series. Managing mux is always an issue and most time consuming one. This series will improve mux code greatly.

Regards,
Santosh
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/8] Series short description
@ 2009-11-29 10:03   ` Shilimkar, Santosh
  0 siblings, 0 replies; 30+ messages in thread
From: Shilimkar, Santosh @ 2009-11-29 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

Tony,
> -----Original Message-----
> From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-
> owner at vger.kernel.org] On Behalf Of Tony Lindgren
> Sent: Thursday, November 26, 2009 5:49 AM
> To: linux-arm-kernel at lists.infradead.org
> Cc: linux-omap at vger.kernel.org
> Subject: [PATCH 0/8] Series short description
> 
> Hi all,
> 
> Here are some omap mux updates for review. These
> are intended for the v2.6.33 merge window.
> 
> Initially this series changes the omap34xx mux
> code, I'm planning on adding 3630, 2420, and 2430
> code later on.
> 
> There are several reasons why we need better mux
> code:
> 
> - We want to make the mux code more generic and this
>   will allow us to use the internal signal names and
>   gpio numbers instead of mux register offsets. The
>   internal signal names stay the same across omap
>   generations for some devices.
> 
> - We need to map mux registers to GPIO registers for
>   dynamic muxing of the GPIO pins during off-idle.
> 
> - We want to be able to override the bootloader mux
>   values for the modded boards, such as the Beagle.
> 
> - We want to have the mux signals and balls available
>   under debugfs for debugging new drivers.
> 
> Some of these might eventually work for other archs
> too, so let me know if you have any comments on that.

Thanks for the series. Managing mux is always an issue and most time consuming one. This series will improve mux code greatly.

Regards,
Santosh
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/8] Series short description
@ 2010-04-15 21:45 David Härdeman
  2010-04-15 21:46   ` David Härdeman
                   ` (8 more replies)
  0 siblings, 9 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:45 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

The following series implements the suggested change to ir-core
to use a 1:31 struct for pulse/space durations, adds two new
raw decoders, converts two users of ir-functions to plain ir-core
and fixes a few small bugs in ir-core.

---

David Härdeman (8):
      ir-core: change duration to be coded as a u32 integer
      ir-core: Add JVC support to ir-core
      ir-core: Add Sony support to ir-core
      ir-core: remove ir-functions usage from dm1105
      ir-core: convert mantis from ir-functions.c
      ir-core: fix double spinlock init in drivers/media/IR/rc-map.c
      ir-core: fix table resize during keymap init
      ir-core: fix some confusing comments


 drivers/media/IR/Kconfig           |   18 ++
 drivers/media/IR/Makefile          |    2 
 drivers/media/IR/ir-core-priv.h    |   63 ++++---
 drivers/media/IR/ir-jvc-decoder.c  |  320 ++++++++++++++++++++++++++++++++++++
 drivers/media/IR/ir-keytable.c     |   12 +
 drivers/media/IR/ir-nec-decoder.c  |  120 ++++++++------
 drivers/media/IR/ir-raw-event.c    |   32 ++--
 drivers/media/IR/ir-rc5-decoder.c  |  105 ++++++------
 drivers/media/IR/ir-rc6-decoder.c  |  221 +++++++++++++------------
 drivers/media/IR/ir-sony-decoder.c |  312 +++++++++++++++++++++++++++++++++++
 drivers/media/IR/ir-sysfs.c        |   12 +
 drivers/media/IR/rc-map.c          |    5 -
 12 files changed, 955 insertions(+), 267 deletions(-)
 create mode 100644 drivers/media/IR/ir-jvc-decoder.c
 create mode 100644 drivers/media/IR/ir-sony-decoder.c

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/8] ir-core: change duration to be coded as a u32 integer
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
@ 2010-04-15 21:46   ` David Härdeman
  2010-04-15 21:46 ` [PATCH 2/8] ir-core: Add JVC support to ir-core David Härdeman
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

This patch implements the agreed upon 1:31 integer encoded pulse/duration
struct for ir-core raw decoders. All decoders have been tested after the
change. Comments are welcome.

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 drivers/media/IR/ir-core-priv.h   |   49 ++++----
 drivers/media/IR/ir-nec-decoder.c |  120 +++++++++++---------
 drivers/media/IR/ir-raw-event.c   |   30 +++--
 drivers/media/IR/ir-rc5-decoder.c |  105 ++++++++----------
 drivers/media/IR/ir-rc6-decoder.c |  221 +++++++++++++++++++------------------
 5 files changed, 271 insertions(+), 254 deletions(-)

diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index ef7f543..707beeb 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -21,7 +21,7 @@
 struct ir_raw_handler {
 	struct list_head list;
 
-	int (*decode)(struct input_dev *input_dev, s64 duration);
+	int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
 	int (*raw_register)(struct input_dev *input_dev);
 	int (*raw_unregister)(struct input_dev *input_dev);
 };
@@ -35,26 +35,28 @@ struct ir_raw_event_ctrl {
 };
 
 /* macros for IR decoders */
-#define PULSE(units)				((units))
-#define SPACE(units)				(-(units))
-#define IS_RESET(duration)			((duration) == 0)
-#define IS_PULSE(duration)			((duration) > 0)
-#define IS_SPACE(duration)			((duration) < 0)
-#define DURATION(duration)			(abs((duration)))
-#define IS_TRANSITION(x, y)			((x) * (y) < 0)
-#define DECREASE_DURATION(duration, amount)			\
-	do {							\
-		if (IS_SPACE(duration))				\
-			duration += (amount);			\
-		else if (IS_PULSE(duration))			\
-			duration -= (amount);			\
-	} while (0)
-
-#define TO_UNITS(duration, unit_len)				\
-	((int)((duration) > 0 ?					\
-		DIV_ROUND_CLOSEST(abs((duration)), (unit_len)) :\
-		-DIV_ROUND_CLOSEST(abs((duration)), (unit_len))))
-#define TO_US(duration)		((int)TO_UNITS(duration, 1000))
+static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin) {
+	return d1 > (d2 - margin);
+}
+
+static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin) {
+	return ((d1 > (d2 - margin)) && (d1 < (d2 + margin)));
+}
+
+static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y) {
+	return x->pulse != y->pulse;
+}
+
+static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) {
+	if (duration > ev->duration)
+		ev->duration = 0;
+	else
+		ev->duration -= duration;
+}
+
+#define TO_US(duration)			(((duration) + 500) / 1000)
+#define TO_STR(is_pulse)		((is_pulse) ? "pulse" : "space")
+#define IS_RESET(ev)			(ev.duration == 0)
 
 /*
  * Routines from ir-keytable.c to be used internally on ir-core and decoders
@@ -76,11 +78,6 @@ void ir_unregister_class(struct input_dev *input_dev);
  */
 int ir_raw_event_register(struct input_dev *input_dev);
 void ir_raw_event_unregister(struct input_dev *input_dev);
-static inline void ir_raw_event_reset(struct input_dev *input_dev)
-{
-	ir_raw_event_store(input_dev, 0);
-	ir_raw_event_handle(input_dev);
-}
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_init(void);
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index 14609d9..ba79233 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -17,13 +17,15 @@
 
 #define NEC_NBITS		32
 #define NEC_UNIT		562500  /* ns */
-#define NEC_HEADER_PULSE	PULSE(16)
-#define NECX_HEADER_PULSE	PULSE(8) /* Less common NEC variant */
-#define NEC_HEADER_SPACE	SPACE(8)
-#define NEC_REPEAT_SPACE	SPACE(4)
-#define NEC_BIT_PULSE		PULSE(1)
-#define NEC_BIT_0_SPACE		SPACE(1)
-#define NEC_BIT_1_SPACE		SPACE(3)
+#define NEC_HEADER_PULSE	(16 * NEC_UNIT)
+#define NECX_HEADER_PULSE	(8  * NEC_UNIT) /* Less common NEC variant */
+#define NEC_HEADER_SPACE	(8  * NEC_UNIT)
+#define NEC_REPEAT_SPACE	(8  * NEC_UNIT)
+#define NEC_BIT_PULSE		(1  * NEC_UNIT)
+#define NEC_BIT_0_SPACE		(1  * NEC_UNIT)
+#define NEC_BIT_1_SPACE		(3  * NEC_UNIT)
+#define	NEC_TRAILER_PULSE	(1  * NEC_UNIT)
+#define	NEC_TRAILER_SPACE	(10 * NEC_UNIT) /* even longer in reality */
 
 /* Used to register nec_decoder clients */
 static LIST_HEAD(decoder_list);
@@ -119,15 +121,14 @@ static struct attribute_group decoder_attribute_group = {
 /**
  * ir_nec_decode() - Decode one NEC pulse or space
  * @input_dev:	the struct input_dev descriptor of the device
- * @duration:	duration in ns of pulse/space
+ * @duration:	the struct ir_raw_event descriptor of the pulse/space
  *
  * This function returns -EINVAL if the pulse violates the state machine
  */
-static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
+static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 {
 	struct decoder_data *data;
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-	int u;
 	u32 scancode;
 	u8 address, not_address, command, not_command;
 
@@ -138,59 +139,88 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
 	if (!data->enabled)
 		return 0;
 
-	if (IS_RESET(duration)) {
+	if (IS_RESET(ev)) {
 		data->state = STATE_INACTIVE;
 		return 0;
 	}
 
-	u = TO_UNITS(duration, NEC_UNIT);
-	if (DURATION(u) == 0)
-		goto out;
-
-	IR_dprintk(2, "NEC decode started at state %d (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 
 	switch (data->state) {
 
 	case STATE_INACTIVE:
-		if (u == NEC_HEADER_PULSE || u == NECX_HEADER_PULSE) {
-			data->count = 0;
-			data->state = STATE_HEADER_SPACE;
-		}
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) &&
+		    !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->count = 0;
+		data->state = STATE_HEADER_SPACE;
 		return 0;
 
 	case STATE_HEADER_SPACE:
-		if (u == NEC_HEADER_SPACE) {
+		if (ev.pulse)
+			break;
+
+		if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) {
 			data->state = STATE_BIT_PULSE;
 			return 0;
-		} else if (u == NEC_REPEAT_SPACE) {
+		} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
 			ir_repeat(input_dev);
 			IR_dprintk(1, "Repeat last key\n");
 			data->state = STATE_TRAILER_PULSE;
 			return 0;
 		}
+
 		break;
 
 	case STATE_BIT_PULSE:
-		if (u == NEC_BIT_PULSE) {
-			data->state = STATE_BIT_SPACE;
-			return 0;
-		}
-		break;
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->state = STATE_BIT_SPACE;
+		return 0;
 
 	case STATE_BIT_SPACE:
-		if (u != NEC_BIT_0_SPACE && u != NEC_BIT_1_SPACE)
+		if (ev.pulse)
 			break;
 
 		data->nec_bits <<= 1;
-		if (u == NEC_BIT_1_SPACE)
+		if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
 			data->nec_bits |= 1;
+		else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
+			break;
 		data->count++;
 
-		if (data->count != NEC_NBITS) {
+		if (data->count == NEC_NBITS)
+			data->state = STATE_TRAILER_PULSE;
+		else
 			data->state = STATE_BIT_PULSE;
-			return 0;
-		}
+
+		return 0;
+
+	case STATE_TRAILER_PULSE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->state = STATE_TRAILER_SPACE;
+		return 0;
+
+	case STATE_TRAILER_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
+			break;
 
 		address     = bitrev8((data->nec_bits >> 24) & 0xff);
 		not_address = bitrev8((data->nec_bits >> 16) & 0xff);
@@ -210,34 +240,18 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
 				   command;
 			IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
 		} else {
-			/* normal NEC */
+			/* Normal NEC */
 			scancode = address << 8 | command;
 			IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
 		}
 
 		ir_keydown(input_dev, scancode, 0);
-		data->state = STATE_TRAILER_PULSE;
+		data->state = STATE_INACTIVE;
 		return 0;
-
-	case STATE_TRAILER_PULSE:
-		if (u > 0) {
-			data->state = STATE_TRAILER_SPACE;
-			return 0;
-		}
-		break;
-
-	case STATE_TRAILER_SPACE:
-		if (u < 0) {
-			data->state = STATE_INACTIVE;
-			return 0;
-		}
-
-		break;
 	}
 
-out:
-	IR_dprintk(1, "NEC decode failed at state %d (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 	data->state = STATE_INACTIVE;
 	return -EINVAL;
 }
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 674442b..59f173c 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -57,12 +57,12 @@ static struct work_struct wq_load;
 
 static void ir_raw_event_work(struct work_struct *work)
 {
-	s64 d;
+	struct ir_raw_event ev;
 	struct ir_raw_event_ctrl *raw =
 		container_of(work, struct ir_raw_event_ctrl, rx_work);
 
-	while (kfifo_out(&raw->kfifo, &d, sizeof(d)) == sizeof(d))
-		RUN_DECODER(decode, raw->input_dev, d);
+	while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
+		RUN_DECODER(decode, raw->input_dev, ev);
 }
 
 int ir_raw_event_register(struct input_dev *input_dev)
@@ -114,21 +114,21 @@ void ir_raw_event_unregister(struct input_dev *input_dev)
 /**
  * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
  * @input_dev:	the struct input_dev device descriptor
- * @duration:	duration of the pulse or space in ns
+ * @ev:		the struct ir_raw_event descriptor of the pulse/space
  *
  * This routine (which may be called from an interrupt context) stores a
  * pulse/space duration for the raw ir decoding state machines. Pulses are
  * signalled as positive values and spaces as negative values. A zero value
  * will reset the decoding state machines.
  */
-int ir_raw_event_store(struct input_dev *input_dev, s64 duration)
+int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
 {
 	struct ir_input_dev *ir = input_get_drvdata(input_dev);
 
 	if (!ir->raw)
 		return -EINVAL;
 
-	if (kfifo_in(&ir->raw->kfifo, &duration, sizeof(duration)) != sizeof(duration))
+	if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
 		return -ENOMEM;
 
 	return 0;
@@ -151,6 +151,7 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type typ
 	struct ir_input_dev	*ir = input_get_drvdata(input_dev);
 	ktime_t			now;
 	s64			delta; /* ns */
+	struct ir_raw_event	ev;
 	int			rc = 0;
 
 	if (!ir->raw)
@@ -163,16 +164,21 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type typ
 	 * being called for the first time, note that delta can't
 	 * possibly be negative.
 	 */
-	if (delta > NSEC_PER_SEC || !ir->raw->last_type)
+	ev.duration = 0;
+	if (delta > IR_MAX_DURATION || !ir->raw->last_type)
 		type |= IR_START_EVENT;
+	else
+		ev.duration = delta;
 
 	if (type & IR_START_EVENT)
 		ir_raw_event_reset(input_dev);
-	else if (ir->raw->last_type & IR_SPACE)
-		rc = ir_raw_event_store(input_dev, -delta);
-	else if (ir->raw->last_type & IR_PULSE)
-		rc = ir_raw_event_store(input_dev, delta);
-	else
+	else if (ir->raw->last_type & IR_SPACE) {
+		ev.pulse = false;
+		rc = ir_raw_event_store(input_dev, &ev);
+	} else if (ir->raw->last_type & IR_PULSE) {
+		ev.pulse = true;
+		rc = ir_raw_event_store(input_dev, &ev);
+	} else
 		return 0;
 
 	ir->raw->last_event = now;
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
index dd5a4d5..23cdb1b 100644
--- a/drivers/media/IR/ir-rc5-decoder.c
+++ b/drivers/media/IR/ir-rc5-decoder.c
@@ -25,8 +25,10 @@
 #define RC5_NBITS		14
 #define RC5X_NBITS		20
 #define CHECK_RC5X_NBITS	8
-#define RC5X_SPACE		SPACE(4)
 #define RC5_UNIT		888888 /* ns */
+#define RC5_BIT_START		(1 * RC5_UNIT)
+#define RC5_BIT_END		(1 * RC5_UNIT)
+#define RC5X_SPACE		(4 * RC5_UNIT)
 
 /* Used to register rc5_decoder clients */
 static LIST_HEAD(decoder_list);
@@ -48,7 +50,7 @@ struct decoder_data {
 	/* State machine control */
 	enum rc5_state		state;
 	u32			rc5_bits;
-	int			last_unit;
+	struct ir_raw_event	prev_ev;
 	unsigned		count;
 	unsigned		wanted_bits;
 };
@@ -124,17 +126,16 @@ static struct attribute_group decoder_attribute_group = {
 /**
  * ir_rc5_decode() - Decode one RC-5 pulse or space
  * @input_dev:	the struct input_dev descriptor of the device
- * @duration:	duration of pulse/space in ns
+ * @ev:		the struct ir_raw_event descriptor of the pulse/space
  *
  * This function returns -EINVAL if the pulse violates the state machine
  */
-static int ir_rc5_decode(struct input_dev *input_dev, s64 duration)
+static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 {
 	struct decoder_data *data;
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
 	u8 toggle;
 	u32 scancode;
-	int u;
 
 	data = get_decoder_data(ir_dev);
 	if (!data)
@@ -143,76 +144,65 @@ static int ir_rc5_decode(struct input_dev *input_dev, s64 duration)
 	if (!data->enabled)
 		return 0;
 
-	if (IS_RESET(duration)) {
+	if (IS_RESET(ev)) {
 		data->state = STATE_INACTIVE;
 		return 0;
 	}
 
-	u = TO_UNITS(duration, RC5_UNIT);
-	if (DURATION(u) == 0)
+	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
 		goto out;
 
 again:
-	IR_dprintk(2, "RC5(x) decode started at state %i (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 
-	if (DURATION(u) == 0 && data->state != STATE_FINISHED)
+	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
 		return 0;
 
 	switch (data->state) {
 
 	case STATE_INACTIVE:
-		if (IS_PULSE(u)) {
-			data->state = STATE_BIT_START;
-			data->count = 1;
-			/* We just need enough bits to get to STATE_CHECK_RC5X */
-			data->wanted_bits = RC5X_NBITS;
-			DECREASE_DURATION(u, 1);
-			goto again;
-		}
-		break;
+		if (!ev.pulse)
+			break;
+
+		data->state = STATE_BIT_START;
+		data->count = 1;
+		/* We just need enough bits to get to STATE_CHECK_RC5X */
+		data->wanted_bits = RC5X_NBITS;
+		decrease_duration(&ev, RC5_BIT_START);
+		goto again;
 
 	case STATE_BIT_START:
-		if (DURATION(u) == 1) {
-			data->rc5_bits <<= 1;
-			if (IS_SPACE(u))
-				data->rc5_bits |= 1;
-			data->count++;
-			data->last_unit = u;
-
-			/*
-			 * If the last bit is zero, a space will merge
-			 * with the silence after the command.
-			 */
-			if (IS_PULSE(u) && data->count == data->wanted_bits) {
-				data->state = STATE_FINISHED;
-				goto again;
-			}
-
-			data->state = STATE_BIT_END;
-			return 0;
-		}
-		break;
+		if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
+			break;
+
+		data->rc5_bits <<= 1;
+		if (!ev.pulse)
+			data->rc5_bits |= 1;
+		data->count++;
+		data->prev_ev = ev;
+		data->state = STATE_BIT_END;
+		return 0;
 
 	case STATE_BIT_END:
-		if (IS_TRANSITION(u, data->last_unit)) {
-			if (data->count == data->wanted_bits)
-				data->state = STATE_FINISHED;
-			else if (data->count == CHECK_RC5X_NBITS)
-				data->state = STATE_CHECK_RC5X;
-			else
-				data->state = STATE_BIT_START;
-
-			DECREASE_DURATION(u, 1);
-			goto again;
-		}
-		break;
+		if (!is_transition(&ev, &data->prev_ev))
+			break;
+
+		if (data->count == data->wanted_bits)
+			data->state = STATE_FINISHED;
+		else if (data->count == CHECK_RC5X_NBITS)
+			data->state = STATE_CHECK_RC5X;
+		else
+			data->state = STATE_BIT_START;
+
+		decrease_duration(&ev, RC5_BIT_END);
+		goto again;
 
 	case STATE_CHECK_RC5X:
-		if (IS_SPACE(u) && DURATION(u) >= DURATION(RC5X_SPACE)) {
+		if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) {
 			/* RC5X */
 			data->wanted_bits = RC5X_NBITS;
-			DECREASE_DURATION(u, DURATION(RC5X_SPACE));
+			decrease_duration(&ev, RC5X_SPACE);
 		} else {
 			/* RC5 */
 			data->wanted_bits = RC5_NBITS;
@@ -221,6 +211,9 @@ again:
 		goto again;
 
 	case STATE_FINISHED:
+		if (ev.pulse)
+			break;
+
 		if (data->wanted_bits == RC5X_NBITS) {
 			/* RC5X */
 			u8 xdata, command, system;
@@ -253,8 +246,8 @@ again:
 	}
 
 out:
-	IR_dprintk(1, "RC5(x) decode failed at state %i (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(1, "RC5(x) decode failed at state %i (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 	data->state = STATE_INACTIVE;
 	return -EINVAL;
 }
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
index ccc5be2..2bf479f 100644
--- a/drivers/media/IR/ir-rc6-decoder.c
+++ b/drivers/media/IR/ir-rc6-decoder.c
@@ -26,8 +26,12 @@
 #define RC6_0_NBITS		16
 #define RC6_6A_SMALL_NBITS	24
 #define RC6_6A_LARGE_NBITS	32
-#define RC6_PREFIX_PULSE	PULSE(6)
-#define RC6_PREFIX_SPACE	SPACE(2)
+#define RC6_PREFIX_PULSE	(6 * RC6_UNIT)
+#define RC6_PREFIX_SPACE	(2 * RC6_UNIT)
+#define RC6_BIT_START		(1 * RC6_UNIT)
+#define RC6_BIT_END		(1 * RC6_UNIT)
+#define RC6_TOGGLE_START	(2 * RC6_UNIT)
+#define RC6_TOGGLE_END		(2 * RC6_UNIT)
 #define RC6_MODE_MASK		0x07	/* for the header bits */
 #define RC6_STARTBIT_MASK	0x08	/* for the header bits */
 #define RC6_6A_MCE_TOGGLE_MASK	0x8000	/* for the body bits */
@@ -63,7 +67,7 @@ struct decoder_data {
 	enum rc6_state		state;
 	u8			header;
 	u32			body;
-	int			last_unit;
+	struct ir_raw_event	prev_ev;
 	bool			toggle;
 	unsigned		count;
 	unsigned		wanted_bits;
@@ -152,17 +156,16 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) {
 /**
  * ir_rc6_decode() - Decode one RC6 pulse or space
  * @input_dev:	the struct input_dev descriptor of the device
- * @duration:	duration of pulse/space in ns
+ * @ev:		the struct ir_raw_event descriptor of the pulse/space
  *
  * This function returns -EINVAL if the pulse violates the state machine
  */
-static int ir_rc6_decode(struct input_dev *input_dev, s64 duration)
+static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 {
 	struct decoder_data *data;
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
 	u32 scancode;
 	u8 toggle;
-	int u;
 
 	data = get_decoder_data(ir_dev);
 	if (!data)
@@ -171,140 +174,144 @@ static int ir_rc6_decode(struct input_dev *input_dev, s64 duration)
 	if (!data->enabled)
 		return 0;
 
-	if (IS_RESET(duration)) {
+	if (IS_RESET(ev)) {
 		data->state = STATE_INACTIVE;
 		return 0;
 	}
 
-	u =  TO_UNITS(duration, RC6_UNIT);
-	if (DURATION(u) == 0)
+	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
 		goto out;
 
 again:
-	IR_dprintk(2, "RC6 decode started at state %i (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 
-	if (DURATION(u) == 0 && data->state != STATE_FINISHED)
+	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
 		return 0;
 
 	switch (data->state) {
 
 	case STATE_INACTIVE:
-		if (u >= RC6_PREFIX_PULSE - 1 && u <= RC6_PREFIX_PULSE + 1) {
-			data->state = STATE_PREFIX_SPACE;
-			data->count = 0;
-			return 0;
-		}
-		break;
+		if (!ev.pulse)
+			break;
+
+		/* Note: larger margin on first pulse since each RC6_UNIT
+		   is quite short and some hardware takes some time to
+		   adjust to the signal */
+		if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
+			break;
+
+		data->state = STATE_PREFIX_SPACE;
+		data->count = 0;
+		return 0;
 
 	case STATE_PREFIX_SPACE:
-		if (u == RC6_PREFIX_SPACE) {
-			data->state = STATE_HEADER_BIT_START;
-			return 0;
-		}
-		break;
+		if (ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
+			break;
+
+		data->state = STATE_HEADER_BIT_START;
+		return 0;
 
 	case STATE_HEADER_BIT_START:
-		if (DURATION(u) == 1) {
-			data->header <<= 1;
-			if (IS_PULSE(u))
-				data->header |= 1;
-			data->count++;
-			data->last_unit = u;
-			data->state = STATE_HEADER_BIT_END;
-			return 0;
-		}
-		break;
+		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
+			break;
+
+		data->header <<= 1;
+		if (ev.pulse)
+			data->header |= 1;
+		data->count++;
+		data->prev_ev = ev;
+		data->state = STATE_HEADER_BIT_END;
+		return 0;
 
 	case STATE_HEADER_BIT_END:
-		if (IS_TRANSITION(u, data->last_unit)) {
-			if (data->count == RC6_HEADER_NBITS)
-				data->state = STATE_TOGGLE_START;
-			else
-				data->state = STATE_HEADER_BIT_START;
+		if (!is_transition(&ev, &data->prev_ev))
+			break;
 
-			DECREASE_DURATION(u, 1);
-			goto again;
-		}
-		break;
+		if (data->count == RC6_HEADER_NBITS)
+			data->state = STATE_TOGGLE_START;
+		else
+			data->state = STATE_HEADER_BIT_START;
+
+		decrease_duration(&ev, RC6_BIT_END);
+		goto again;
 
 	case STATE_TOGGLE_START:
-		if (DURATION(u) == 2) {
-			data->toggle = IS_PULSE(u);
-			data->last_unit = u;
-			data->state = STATE_TOGGLE_END;
-			return 0;
-		}
-		break;
+		if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
+			break;
+
+		data->toggle = ev.pulse;
+		data->prev_ev = ev;
+		data->state = STATE_TOGGLE_END;
+		return 0;
 
 	case STATE_TOGGLE_END:
-		if (IS_TRANSITION(u, data->last_unit) && DURATION(u) >= 2) {
-			data->state = STATE_BODY_BIT_START;
-			data->last_unit = u;
-			DECREASE_DURATION(u, 2);
-			data->count = 0;
+		if (!is_transition(&ev, &data->prev_ev) ||
+		    !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
+			break;
 
-			if (!(data->header & RC6_STARTBIT_MASK)) {
-				IR_dprintk(1, "RC6 invalid start bit\n");
-				break;
-			}
+		if (!(data->header & RC6_STARTBIT_MASK)) {
+			IR_dprintk(1, "RC6 invalid start bit\n");
+			break;
+		}
 
-			switch (rc6_mode(data)) {
-			case RC6_MODE_0:
-				data->wanted_bits = RC6_0_NBITS;
-				break;
-			case RC6_MODE_6A:
-				/* This might look weird, but we basically
-				   check the value of the first body bit to
-				   determine the number of bits in mode 6A */
-				if ((DURATION(u) == 0 && IS_SPACE(data->last_unit)) || DURATION(u) > 0)
-					data->wanted_bits = RC6_6A_LARGE_NBITS;
-				else
-					data->wanted_bits = RC6_6A_SMALL_NBITS;
-				break;
-			default:
-				IR_dprintk(1, "RC6 unknown mode\n");
-				goto out;
-			}
-			goto again;
+		data->state = STATE_BODY_BIT_START;
+		data->prev_ev = ev;
+		decrease_duration(&ev, RC6_TOGGLE_END);
+		data->count = 0;
+
+		switch (rc6_mode(data)) {
+		case RC6_MODE_0:
+			data->wanted_bits = RC6_0_NBITS;
+			break;
+		case RC6_MODE_6A:
+			/* This might look weird, but we basically
+			   check the value of the first body bit to
+			   determine the number of bits in mode 6A */
+			if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) ||
+			    geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
+				data->wanted_bits = RC6_6A_LARGE_NBITS;
+			else
+				data->wanted_bits = RC6_6A_SMALL_NBITS;
+			break;
+		default:
+			IR_dprintk(1, "RC6 unknown mode\n");
+			goto out;
 		}
-		break;
+		goto again;
 
 	case STATE_BODY_BIT_START:
-		if (DURATION(u) == 1) {
-			data->body <<= 1;
-			if (IS_PULSE(u))
-				data->body |= 1;
-			data->count++;
-			data->last_unit = u;
-
-			/*
-			 * If the last bit is one, a space will merge
-			 * with the silence after the command.
-			 */
-			if (IS_PULSE(u) && data->count == data->wanted_bits) {
-				data->state = STATE_FINISHED;
-				goto again;
-			}
+		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
+			break;
 
-			data->state = STATE_BODY_BIT_END;
-			return 0;
-		}
-		break;
+		data->body <<= 1;
+		if (ev.pulse)
+			data->body |= 1;
+		data->count++;
+		data->prev_ev = ev;
+
+		data->state = STATE_BODY_BIT_END;
+		return 0;
 
 	case STATE_BODY_BIT_END:
-		if (IS_TRANSITION(u, data->last_unit)) {
-			if (data->count == data->wanted_bits)
-				data->state = STATE_FINISHED;
-			else
-				data->state = STATE_BODY_BIT_START;
+		if (!is_transition(&ev, &data->prev_ev))
+			break;
 
-			DECREASE_DURATION(u, 1);
-			goto again;
-		}
-		break;
+		if (data->count == data->wanted_bits)
+			data->state = STATE_FINISHED;
+		else
+			data->state = STATE_BODY_BIT_START;
+
+		decrease_duration(&ev, RC6_BIT_END);
+		goto again;
 
 	case STATE_FINISHED:
+		if (ev.pulse)
+			break;
+
 		switch (rc6_mode(data)) {
 		case RC6_MODE_0:
 			scancode = data->body & 0xffff;
@@ -335,8 +342,8 @@ again:
 	}
 
 out:
-	IR_dprintk(1, "RC6 decode failed at state %i (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 	data->state = STATE_INACTIVE;
 	return -EINVAL;
 }
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index ab3bd30..26110cc 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -127,9 +127,21 @@ void ir_keydown(struct input_dev *dev, int scancode, u8 toggle);
 
 /* From ir-raw-event.c */
 
+struct ir_raw_event {
+	unsigned                        pulse:1;
+	unsigned                        duration:31;
+};
+
+#define IR_MAX_DURATION                 0x7FFFFFFF      /* a bit more than 2 seconds */
+
 void ir_raw_event_handle(struct input_dev *input_dev);
-int ir_raw_event_store(struct input_dev *input_dev, s64 duration);
+int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
 int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
-
+static inline void ir_raw_event_reset(struct input_dev *input_dev)
+{
+	struct ir_raw_event ev = { .pulse = false, .duration = 0 };
+	ir_raw_event_store(input_dev, &ev);
+	ir_raw_event_handle(input_dev);
+}
 
 #endif /* _IR_CORE */

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 1/8] ir-core: change duration to be coded as a u32 integer
@ 2010-04-15 21:46   ` David Härdeman
  0 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

This patch implements the agreed upon 1:31 integer encoded pulse/duration
struct for ir-core raw decoders. All decoders have been tested after the
change. Comments are welcome.

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 drivers/media/IR/ir-core-priv.h   |   49 ++++----
 drivers/media/IR/ir-nec-decoder.c |  120 +++++++++++---------
 drivers/media/IR/ir-raw-event.c   |   30 +++--
 drivers/media/IR/ir-rc5-decoder.c |  105 ++++++++----------
 drivers/media/IR/ir-rc6-decoder.c |  221 +++++++++++++++++++------------------
 5 files changed, 271 insertions(+), 254 deletions(-)

diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index ef7f543..707beeb 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -21,7 +21,7 @@
 struct ir_raw_handler {
 	struct list_head list;
 
-	int (*decode)(struct input_dev *input_dev, s64 duration);
+	int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
 	int (*raw_register)(struct input_dev *input_dev);
 	int (*raw_unregister)(struct input_dev *input_dev);
 };
@@ -35,26 +35,28 @@ struct ir_raw_event_ctrl {
 };
 
 /* macros for IR decoders */
-#define PULSE(units)				((units))
-#define SPACE(units)				(-(units))
-#define IS_RESET(duration)			((duration) == 0)
-#define IS_PULSE(duration)			((duration) > 0)
-#define IS_SPACE(duration)			((duration) < 0)
-#define DURATION(duration)			(abs((duration)))
-#define IS_TRANSITION(x, y)			((x) * (y) < 0)
-#define DECREASE_DURATION(duration, amount)			\
-	do {							\
-		if (IS_SPACE(duration))				\
-			duration += (amount);			\
-		else if (IS_PULSE(duration))			\
-			duration -= (amount);			\
-	} while (0)
-
-#define TO_UNITS(duration, unit_len)				\
-	((int)((duration) > 0 ?					\
-		DIV_ROUND_CLOSEST(abs((duration)), (unit_len)) :\
-		-DIV_ROUND_CLOSEST(abs((duration)), (unit_len))))
-#define TO_US(duration)		((int)TO_UNITS(duration, 1000))
+static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin) {
+	return d1 > (d2 - margin);
+}
+
+static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin) {
+	return ((d1 > (d2 - margin)) && (d1 < (d2 + margin)));
+}
+
+static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y) {
+	return x->pulse != y->pulse;
+}
+
+static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) {
+	if (duration > ev->duration)
+		ev->duration = 0;
+	else
+		ev->duration -= duration;
+}
+
+#define TO_US(duration)			(((duration) + 500) / 1000)
+#define TO_STR(is_pulse)		((is_pulse) ? "pulse" : "space")
+#define IS_RESET(ev)			(ev.duration == 0)
 
 /*
  * Routines from ir-keytable.c to be used internally on ir-core and decoders
@@ -76,11 +78,6 @@ void ir_unregister_class(struct input_dev *input_dev);
  */
 int ir_raw_event_register(struct input_dev *input_dev);
 void ir_raw_event_unregister(struct input_dev *input_dev);
-static inline void ir_raw_event_reset(struct input_dev *input_dev)
-{
-	ir_raw_event_store(input_dev, 0);
-	ir_raw_event_handle(input_dev);
-}
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_init(void);
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index 14609d9..ba79233 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -17,13 +17,15 @@
 
 #define NEC_NBITS		32
 #define NEC_UNIT		562500  /* ns */
-#define NEC_HEADER_PULSE	PULSE(16)
-#define NECX_HEADER_PULSE	PULSE(8) /* Less common NEC variant */
-#define NEC_HEADER_SPACE	SPACE(8)
-#define NEC_REPEAT_SPACE	SPACE(4)
-#define NEC_BIT_PULSE		PULSE(1)
-#define NEC_BIT_0_SPACE		SPACE(1)
-#define NEC_BIT_1_SPACE		SPACE(3)
+#define NEC_HEADER_PULSE	(16 * NEC_UNIT)
+#define NECX_HEADER_PULSE	(8  * NEC_UNIT) /* Less common NEC variant */
+#define NEC_HEADER_SPACE	(8  * NEC_UNIT)
+#define NEC_REPEAT_SPACE	(8  * NEC_UNIT)
+#define NEC_BIT_PULSE		(1  * NEC_UNIT)
+#define NEC_BIT_0_SPACE		(1  * NEC_UNIT)
+#define NEC_BIT_1_SPACE		(3  * NEC_UNIT)
+#define	NEC_TRAILER_PULSE	(1  * NEC_UNIT)
+#define	NEC_TRAILER_SPACE	(10 * NEC_UNIT) /* even longer in reality */
 
 /* Used to register nec_decoder clients */
 static LIST_HEAD(decoder_list);
@@ -119,15 +121,14 @@ static struct attribute_group decoder_attribute_group = {
 /**
  * ir_nec_decode() - Decode one NEC pulse or space
  * @input_dev:	the struct input_dev descriptor of the device
- * @duration:	duration in ns of pulse/space
+ * @duration:	the struct ir_raw_event descriptor of the pulse/space
  *
  * This function returns -EINVAL if the pulse violates the state machine
  */
-static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
+static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 {
 	struct decoder_data *data;
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-	int u;
 	u32 scancode;
 	u8 address, not_address, command, not_command;
 
@@ -138,59 +139,88 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
 	if (!data->enabled)
 		return 0;
 
-	if (IS_RESET(duration)) {
+	if (IS_RESET(ev)) {
 		data->state = STATE_INACTIVE;
 		return 0;
 	}
 
-	u = TO_UNITS(duration, NEC_UNIT);
-	if (DURATION(u) == 0)
-		goto out;
-
-	IR_dprintk(2, "NEC decode started at state %d (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 
 	switch (data->state) {
 
 	case STATE_INACTIVE:
-		if (u == NEC_HEADER_PULSE || u == NECX_HEADER_PULSE) {
-			data->count = 0;
-			data->state = STATE_HEADER_SPACE;
-		}
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) &&
+		    !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->count = 0;
+		data->state = STATE_HEADER_SPACE;
 		return 0;
 
 	case STATE_HEADER_SPACE:
-		if (u == NEC_HEADER_SPACE) {
+		if (ev.pulse)
+			break;
+
+		if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) {
 			data->state = STATE_BIT_PULSE;
 			return 0;
-		} else if (u == NEC_REPEAT_SPACE) {
+		} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
 			ir_repeat(input_dev);
 			IR_dprintk(1, "Repeat last key\n");
 			data->state = STATE_TRAILER_PULSE;
 			return 0;
 		}
+
 		break;
 
 	case STATE_BIT_PULSE:
-		if (u == NEC_BIT_PULSE) {
-			data->state = STATE_BIT_SPACE;
-			return 0;
-		}
-		break;
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->state = STATE_BIT_SPACE;
+		return 0;
 
 	case STATE_BIT_SPACE:
-		if (u != NEC_BIT_0_SPACE && u != NEC_BIT_1_SPACE)
+		if (ev.pulse)
 			break;
 
 		data->nec_bits <<= 1;
-		if (u == NEC_BIT_1_SPACE)
+		if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
 			data->nec_bits |= 1;
+		else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
+			break;
 		data->count++;
 
-		if (data->count != NEC_NBITS) {
+		if (data->count == NEC_NBITS)
+			data->state = STATE_TRAILER_PULSE;
+		else
 			data->state = STATE_BIT_PULSE;
-			return 0;
-		}
+
+		return 0;
+
+	case STATE_TRAILER_PULSE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
+			break;
+
+		data->state = STATE_TRAILER_SPACE;
+		return 0;
+
+	case STATE_TRAILER_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
+			break;
 
 		address     = bitrev8((data->nec_bits >> 24) & 0xff);
 		not_address = bitrev8((data->nec_bits >> 16) & 0xff);
@@ -210,34 +240,18 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
 				   command;
 			IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
 		} else {
-			/* normal NEC */
+			/* Normal NEC */
 			scancode = address << 8 | command;
 			IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
 		}
 
 		ir_keydown(input_dev, scancode, 0);
-		data->state = STATE_TRAILER_PULSE;
+		data->state = STATE_INACTIVE;
 		return 0;
-
-	case STATE_TRAILER_PULSE:
-		if (u > 0) {
-			data->state = STATE_TRAILER_SPACE;
-			return 0;
-		}
-		break;
-
-	case STATE_TRAILER_SPACE:
-		if (u < 0) {
-			data->state = STATE_INACTIVE;
-			return 0;
-		}
-
-		break;
 	}
 
-out:
-	IR_dprintk(1, "NEC decode failed at state %d (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 	data->state = STATE_INACTIVE;
 	return -EINVAL;
 }
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 674442b..59f173c 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -57,12 +57,12 @@ static struct work_struct wq_load;
 
 static void ir_raw_event_work(struct work_struct *work)
 {
-	s64 d;
+	struct ir_raw_event ev;
 	struct ir_raw_event_ctrl *raw =
 		container_of(work, struct ir_raw_event_ctrl, rx_work);
 
-	while (kfifo_out(&raw->kfifo, &d, sizeof(d)) == sizeof(d))
-		RUN_DECODER(decode, raw->input_dev, d);
+	while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
+		RUN_DECODER(decode, raw->input_dev, ev);
 }
 
 int ir_raw_event_register(struct input_dev *input_dev)
@@ -114,21 +114,21 @@ void ir_raw_event_unregister(struct input_dev *input_dev)
 /**
  * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
  * @input_dev:	the struct input_dev device descriptor
- * @duration:	duration of the pulse or space in ns
+ * @ev:		the struct ir_raw_event descriptor of the pulse/space
  *
  * This routine (which may be called from an interrupt context) stores a
  * pulse/space duration for the raw ir decoding state machines. Pulses are
  * signalled as positive values and spaces as negative values. A zero value
  * will reset the decoding state machines.
  */
-int ir_raw_event_store(struct input_dev *input_dev, s64 duration)
+int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
 {
 	struct ir_input_dev *ir = input_get_drvdata(input_dev);
 
 	if (!ir->raw)
 		return -EINVAL;
 
-	if (kfifo_in(&ir->raw->kfifo, &duration, sizeof(duration)) != sizeof(duration))
+	if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
 		return -ENOMEM;
 
 	return 0;
@@ -151,6 +151,7 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type typ
 	struct ir_input_dev	*ir = input_get_drvdata(input_dev);
 	ktime_t			now;
 	s64			delta; /* ns */
+	struct ir_raw_event	ev;
 	int			rc = 0;
 
 	if (!ir->raw)
@@ -163,16 +164,21 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type typ
 	 * being called for the first time, note that delta can't
 	 * possibly be negative.
 	 */
-	if (delta > NSEC_PER_SEC || !ir->raw->last_type)
+	ev.duration = 0;
+	if (delta > IR_MAX_DURATION || !ir->raw->last_type)
 		type |= IR_START_EVENT;
+	else
+		ev.duration = delta;
 
 	if (type & IR_START_EVENT)
 		ir_raw_event_reset(input_dev);
-	else if (ir->raw->last_type & IR_SPACE)
-		rc = ir_raw_event_store(input_dev, -delta);
-	else if (ir->raw->last_type & IR_PULSE)
-		rc = ir_raw_event_store(input_dev, delta);
-	else
+	else if (ir->raw->last_type & IR_SPACE) {
+		ev.pulse = false;
+		rc = ir_raw_event_store(input_dev, &ev);
+	} else if (ir->raw->last_type & IR_PULSE) {
+		ev.pulse = true;
+		rc = ir_raw_event_store(input_dev, &ev);
+	} else
 		return 0;
 
 	ir->raw->last_event = now;
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
index dd5a4d5..23cdb1b 100644
--- a/drivers/media/IR/ir-rc5-decoder.c
+++ b/drivers/media/IR/ir-rc5-decoder.c
@@ -25,8 +25,10 @@
 #define RC5_NBITS		14
 #define RC5X_NBITS		20
 #define CHECK_RC5X_NBITS	8
-#define RC5X_SPACE		SPACE(4)
 #define RC5_UNIT		888888 /* ns */
+#define RC5_BIT_START		(1 * RC5_UNIT)
+#define RC5_BIT_END		(1 * RC5_UNIT)
+#define RC5X_SPACE		(4 * RC5_UNIT)
 
 /* Used to register rc5_decoder clients */
 static LIST_HEAD(decoder_list);
@@ -48,7 +50,7 @@ struct decoder_data {
 	/* State machine control */
 	enum rc5_state		state;
 	u32			rc5_bits;
-	int			last_unit;
+	struct ir_raw_event	prev_ev;
 	unsigned		count;
 	unsigned		wanted_bits;
 };
@@ -124,17 +126,16 @@ static struct attribute_group decoder_attribute_group = {
 /**
  * ir_rc5_decode() - Decode one RC-5 pulse or space
  * @input_dev:	the struct input_dev descriptor of the device
- * @duration:	duration of pulse/space in ns
+ * @ev:		the struct ir_raw_event descriptor of the pulse/space
  *
  * This function returns -EINVAL if the pulse violates the state machine
  */
-static int ir_rc5_decode(struct input_dev *input_dev, s64 duration)
+static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 {
 	struct decoder_data *data;
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
 	u8 toggle;
 	u32 scancode;
-	int u;
 
 	data = get_decoder_data(ir_dev);
 	if (!data)
@@ -143,76 +144,65 @@ static int ir_rc5_decode(struct input_dev *input_dev, s64 duration)
 	if (!data->enabled)
 		return 0;
 
-	if (IS_RESET(duration)) {
+	if (IS_RESET(ev)) {
 		data->state = STATE_INACTIVE;
 		return 0;
 	}
 
-	u = TO_UNITS(duration, RC5_UNIT);
-	if (DURATION(u) == 0)
+	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
 		goto out;
 
 again:
-	IR_dprintk(2, "RC5(x) decode started at state %i (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 
-	if (DURATION(u) == 0 && data->state != STATE_FINISHED)
+	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
 		return 0;
 
 	switch (data->state) {
 
 	case STATE_INACTIVE:
-		if (IS_PULSE(u)) {
-			data->state = STATE_BIT_START;
-			data->count = 1;
-			/* We just need enough bits to get to STATE_CHECK_RC5X */
-			data->wanted_bits = RC5X_NBITS;
-			DECREASE_DURATION(u, 1);
-			goto again;
-		}
-		break;
+		if (!ev.pulse)
+			break;
+
+		data->state = STATE_BIT_START;
+		data->count = 1;
+		/* We just need enough bits to get to STATE_CHECK_RC5X */
+		data->wanted_bits = RC5X_NBITS;
+		decrease_duration(&ev, RC5_BIT_START);
+		goto again;
 
 	case STATE_BIT_START:
-		if (DURATION(u) == 1) {
-			data->rc5_bits <<= 1;
-			if (IS_SPACE(u))
-				data->rc5_bits |= 1;
-			data->count++;
-			data->last_unit = u;
-
-			/*
-			 * If the last bit is zero, a space will merge
-			 * with the silence after the command.
-			 */
-			if (IS_PULSE(u) && data->count == data->wanted_bits) {
-				data->state = STATE_FINISHED;
-				goto again;
-			}
-
-			data->state = STATE_BIT_END;
-			return 0;
-		}
-		break;
+		if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
+			break;
+
+		data->rc5_bits <<= 1;
+		if (!ev.pulse)
+			data->rc5_bits |= 1;
+		data->count++;
+		data->prev_ev = ev;
+		data->state = STATE_BIT_END;
+		return 0;
 
 	case STATE_BIT_END:
-		if (IS_TRANSITION(u, data->last_unit)) {
-			if (data->count == data->wanted_bits)
-				data->state = STATE_FINISHED;
-			else if (data->count == CHECK_RC5X_NBITS)
-				data->state = STATE_CHECK_RC5X;
-			else
-				data->state = STATE_BIT_START;
-
-			DECREASE_DURATION(u, 1);
-			goto again;
-		}
-		break;
+		if (!is_transition(&ev, &data->prev_ev))
+			break;
+
+		if (data->count == data->wanted_bits)
+			data->state = STATE_FINISHED;
+		else if (data->count == CHECK_RC5X_NBITS)
+			data->state = STATE_CHECK_RC5X;
+		else
+			data->state = STATE_BIT_START;
+
+		decrease_duration(&ev, RC5_BIT_END);
+		goto again;
 
 	case STATE_CHECK_RC5X:
-		if (IS_SPACE(u) && DURATION(u) >= DURATION(RC5X_SPACE)) {
+		if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) {
 			/* RC5X */
 			data->wanted_bits = RC5X_NBITS;
-			DECREASE_DURATION(u, DURATION(RC5X_SPACE));
+			decrease_duration(&ev, RC5X_SPACE);
 		} else {
 			/* RC5 */
 			data->wanted_bits = RC5_NBITS;
@@ -221,6 +211,9 @@ again:
 		goto again;
 
 	case STATE_FINISHED:
+		if (ev.pulse)
+			break;
+
 		if (data->wanted_bits == RC5X_NBITS) {
 			/* RC5X */
 			u8 xdata, command, system;
@@ -253,8 +246,8 @@ again:
 	}
 
 out:
-	IR_dprintk(1, "RC5(x) decode failed at state %i (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(1, "RC5(x) decode failed at state %i (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 	data->state = STATE_INACTIVE;
 	return -EINVAL;
 }
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
index ccc5be2..2bf479f 100644
--- a/drivers/media/IR/ir-rc6-decoder.c
+++ b/drivers/media/IR/ir-rc6-decoder.c
@@ -26,8 +26,12 @@
 #define RC6_0_NBITS		16
 #define RC6_6A_SMALL_NBITS	24
 #define RC6_6A_LARGE_NBITS	32
-#define RC6_PREFIX_PULSE	PULSE(6)
-#define RC6_PREFIX_SPACE	SPACE(2)
+#define RC6_PREFIX_PULSE	(6 * RC6_UNIT)
+#define RC6_PREFIX_SPACE	(2 * RC6_UNIT)
+#define RC6_BIT_START		(1 * RC6_UNIT)
+#define RC6_BIT_END		(1 * RC6_UNIT)
+#define RC6_TOGGLE_START	(2 * RC6_UNIT)
+#define RC6_TOGGLE_END		(2 * RC6_UNIT)
 #define RC6_MODE_MASK		0x07	/* for the header bits */
 #define RC6_STARTBIT_MASK	0x08	/* for the header bits */
 #define RC6_6A_MCE_TOGGLE_MASK	0x8000	/* for the body bits */
@@ -63,7 +67,7 @@ struct decoder_data {
 	enum rc6_state		state;
 	u8			header;
 	u32			body;
-	int			last_unit;
+	struct ir_raw_event	prev_ev;
 	bool			toggle;
 	unsigned		count;
 	unsigned		wanted_bits;
@@ -152,17 +156,16 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) {
 /**
  * ir_rc6_decode() - Decode one RC6 pulse or space
  * @input_dev:	the struct input_dev descriptor of the device
- * @duration:	duration of pulse/space in ns
+ * @ev:		the struct ir_raw_event descriptor of the pulse/space
  *
  * This function returns -EINVAL if the pulse violates the state machine
  */
-static int ir_rc6_decode(struct input_dev *input_dev, s64 duration)
+static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 {
 	struct decoder_data *data;
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
 	u32 scancode;
 	u8 toggle;
-	int u;
 
 	data = get_decoder_data(ir_dev);
 	if (!data)
@@ -171,140 +174,144 @@ static int ir_rc6_decode(struct input_dev *input_dev, s64 duration)
 	if (!data->enabled)
 		return 0;
 
-	if (IS_RESET(duration)) {
+	if (IS_RESET(ev)) {
 		data->state = STATE_INACTIVE;
 		return 0;
 	}
 
-	u =  TO_UNITS(duration, RC6_UNIT);
-	if (DURATION(u) == 0)
+	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
 		goto out;
 
 again:
-	IR_dprintk(2, "RC6 decode started at state %i (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 
-	if (DURATION(u) == 0 && data->state != STATE_FINISHED)
+	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
 		return 0;
 
 	switch (data->state) {
 
 	case STATE_INACTIVE:
-		if (u >= RC6_PREFIX_PULSE - 1 && u <= RC6_PREFIX_PULSE + 1) {
-			data->state = STATE_PREFIX_SPACE;
-			data->count = 0;
-			return 0;
-		}
-		break;
+		if (!ev.pulse)
+			break;
+
+		/* Note: larger margin on first pulse since each RC6_UNIT
+		   is quite short and some hardware takes some time to
+		   adjust to the signal */
+		if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
+			break;
+
+		data->state = STATE_PREFIX_SPACE;
+		data->count = 0;
+		return 0;
 
 	case STATE_PREFIX_SPACE:
-		if (u == RC6_PREFIX_SPACE) {
-			data->state = STATE_HEADER_BIT_START;
-			return 0;
-		}
-		break;
+		if (ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
+			break;
+
+		data->state = STATE_HEADER_BIT_START;
+		return 0;
 
 	case STATE_HEADER_BIT_START:
-		if (DURATION(u) == 1) {
-			data->header <<= 1;
-			if (IS_PULSE(u))
-				data->header |= 1;
-			data->count++;
-			data->last_unit = u;
-			data->state = STATE_HEADER_BIT_END;
-			return 0;
-		}
-		break;
+		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
+			break;
+
+		data->header <<= 1;
+		if (ev.pulse)
+			data->header |= 1;
+		data->count++;
+		data->prev_ev = ev;
+		data->state = STATE_HEADER_BIT_END;
+		return 0;
 
 	case STATE_HEADER_BIT_END:
-		if (IS_TRANSITION(u, data->last_unit)) {
-			if (data->count == RC6_HEADER_NBITS)
-				data->state = STATE_TOGGLE_START;
-			else
-				data->state = STATE_HEADER_BIT_START;
+		if (!is_transition(&ev, &data->prev_ev))
+			break;
 
-			DECREASE_DURATION(u, 1);
-			goto again;
-		}
-		break;
+		if (data->count == RC6_HEADER_NBITS)
+			data->state = STATE_TOGGLE_START;
+		else
+			data->state = STATE_HEADER_BIT_START;
+
+		decrease_duration(&ev, RC6_BIT_END);
+		goto again;
 
 	case STATE_TOGGLE_START:
-		if (DURATION(u) == 2) {
-			data->toggle = IS_PULSE(u);
-			data->last_unit = u;
-			data->state = STATE_TOGGLE_END;
-			return 0;
-		}
-		break;
+		if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
+			break;
+
+		data->toggle = ev.pulse;
+		data->prev_ev = ev;
+		data->state = STATE_TOGGLE_END;
+		return 0;
 
 	case STATE_TOGGLE_END:
-		if (IS_TRANSITION(u, data->last_unit) && DURATION(u) >= 2) {
-			data->state = STATE_BODY_BIT_START;
-			data->last_unit = u;
-			DECREASE_DURATION(u, 2);
-			data->count = 0;
+		if (!is_transition(&ev, &data->prev_ev) ||
+		    !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
+			break;
 
-			if (!(data->header & RC6_STARTBIT_MASK)) {
-				IR_dprintk(1, "RC6 invalid start bit\n");
-				break;
-			}
+		if (!(data->header & RC6_STARTBIT_MASK)) {
+			IR_dprintk(1, "RC6 invalid start bit\n");
+			break;
+		}
 
-			switch (rc6_mode(data)) {
-			case RC6_MODE_0:
-				data->wanted_bits = RC6_0_NBITS;
-				break;
-			case RC6_MODE_6A:
-				/* This might look weird, but we basically
-				   check the value of the first body bit to
-				   determine the number of bits in mode 6A */
-				if ((DURATION(u) == 0 && IS_SPACE(data->last_unit)) || DURATION(u) > 0)
-					data->wanted_bits = RC6_6A_LARGE_NBITS;
-				else
-					data->wanted_bits = RC6_6A_SMALL_NBITS;
-				break;
-			default:
-				IR_dprintk(1, "RC6 unknown mode\n");
-				goto out;
-			}
-			goto again;
+		data->state = STATE_BODY_BIT_START;
+		data->prev_ev = ev;
+		decrease_duration(&ev, RC6_TOGGLE_END);
+		data->count = 0;
+
+		switch (rc6_mode(data)) {
+		case RC6_MODE_0:
+			data->wanted_bits = RC6_0_NBITS;
+			break;
+		case RC6_MODE_6A:
+			/* This might look weird, but we basically
+			   check the value of the first body bit to
+			   determine the number of bits in mode 6A */
+			if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) ||
+			    geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
+				data->wanted_bits = RC6_6A_LARGE_NBITS;
+			else
+				data->wanted_bits = RC6_6A_SMALL_NBITS;
+			break;
+		default:
+			IR_dprintk(1, "RC6 unknown mode\n");
+			goto out;
 		}
-		break;
+		goto again;
 
 	case STATE_BODY_BIT_START:
-		if (DURATION(u) == 1) {
-			data->body <<= 1;
-			if (IS_PULSE(u))
-				data->body |= 1;
-			data->count++;
-			data->last_unit = u;
-
-			/*
-			 * If the last bit is one, a space will merge
-			 * with the silence after the command.
-			 */
-			if (IS_PULSE(u) && data->count == data->wanted_bits) {
-				data->state = STATE_FINISHED;
-				goto again;
-			}
+		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
+			break;
 
-			data->state = STATE_BODY_BIT_END;
-			return 0;
-		}
-		break;
+		data->body <<= 1;
+		if (ev.pulse)
+			data->body |= 1;
+		data->count++;
+		data->prev_ev = ev;
+
+		data->state = STATE_BODY_BIT_END;
+		return 0;
 
 	case STATE_BODY_BIT_END:
-		if (IS_TRANSITION(u, data->last_unit)) {
-			if (data->count == data->wanted_bits)
-				data->state = STATE_FINISHED;
-			else
-				data->state = STATE_BODY_BIT_START;
+		if (!is_transition(&ev, &data->prev_ev))
+			break;
 
-			DECREASE_DURATION(u, 1);
-			goto again;
-		}
-		break;
+		if (data->count == data->wanted_bits)
+			data->state = STATE_FINISHED;
+		else
+			data->state = STATE_BODY_BIT_START;
+
+		decrease_duration(&ev, RC6_BIT_END);
+		goto again;
 
 	case STATE_FINISHED:
+		if (ev.pulse)
+			break;
+
 		switch (rc6_mode(data)) {
 		case RC6_MODE_0:
 			scancode = data->body & 0xffff;
@@ -335,8 +342,8 @@ again:
 	}
 
 out:
-	IR_dprintk(1, "RC6 decode failed at state %i (%i units, %ius)\n",
-		   data->state, u, TO_US(duration));
+	IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 	data->state = STATE_INACTIVE;
 	return -EINVAL;
 }
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index ab3bd30..26110cc 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -127,9 +127,21 @@ void ir_keydown(struct input_dev *dev, int scancode, u8 toggle);
 
 /* From ir-raw-event.c */
 
+struct ir_raw_event {
+	unsigned                        pulse:1;
+	unsigned                        duration:31;
+};
+
+#define IR_MAX_DURATION                 0x7FFFFFFF      /* a bit more than 2 seconds */
+
 void ir_raw_event_handle(struct input_dev *input_dev);
-int ir_raw_event_store(struct input_dev *input_dev, s64 duration);
+int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
 int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
-
+static inline void ir_raw_event_reset(struct input_dev *input_dev)
+{
+	struct ir_raw_event ev = { .pulse = false, .duration = 0 };
+	ir_raw_event_store(input_dev, &ev);
+	ir_raw_event_handle(input_dev);
+}
 
 #endif /* _IR_CORE */


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 2/8] ir-core: Add JVC support to ir-core
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
  2010-04-15 21:46   ` David Härdeman
@ 2010-04-15 21:46 ` David Härdeman
  2010-04-15 21:46 ` [PATCH 3/8] ir-core: Add Sony " David Härdeman
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

This patch adds a JVC decoder to ir-core.

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 drivers/media/IR/Kconfig          |    9 +
 drivers/media/IR/Makefile         |    1 
 drivers/media/IR/ir-core-priv.h   |    7 +
 drivers/media/IR/ir-jvc-decoder.c |  320 +++++++++++++++++++++++++++++++++++++
 drivers/media/IR/ir-raw-event.c   |    1 
 drivers/media/IR/ir-sysfs.c       |    4 
 6 files changed, 342 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/IR/ir-jvc-decoder.c

diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
index ee66d16..179e4c3 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/IR/Kconfig
@@ -36,3 +36,12 @@ config IR_RC6_DECODER
 	---help---
 	   Enable this option if you have an infrared remote control which
 	   uses the RC6 protocol, and you need software decoding support.
+
+config IR_JVC_DECODER
+	tristate "Enable IR raw decoder for the JVC protocol"
+	depends on IR_CORE
+	default y
+
+	---help---
+	   Enable this option if you have an infrared remote control which
+	   uses the JVC protocol, and you need software decoding support.
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
index 792d9ca..8d0098f 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/IR/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_VIDEO_IR) += ir-common.o
 obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
 obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
 obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
+obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index 707beeb..4b1a21d 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -111,4 +111,11 @@ void ir_raw_init(void);
 #define load_rc6_decode()	0
 #endif
 
+/* from ir-jvc-decoder.c */
+#ifdef CONFIG_IR_JVC_DECODER_MODULE
+#define load_jvc_decode()	request_module("ir-jvc-decoder")
+#else
+#define load_jvc_decode()	0
+#endif
+
 #endif /* _IR_RAW_EVENT */
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c
new file mode 100644
index 0000000..0b80494
--- /dev/null
+++ b/drivers/media/IR/ir-jvc-decoder.c
@@ -0,0 +1,320 @@
+/* ir-jvc-decoder.c - handle JVC IR Pulse/Space protocol
+ *
+ * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bitrev.h>
+#include "ir-core-priv.h"
+
+#define JVC_NBITS		16		/* dev(8) + func(8) */
+#define JVC_UNIT		525000		/* ns */
+#define JVC_HEADER_PULSE	(16 * JVC_UNIT) /* lack of header -> repeat */
+#define JVC_HEADER_SPACE	(8  * JVC_UNIT)
+#define JVC_BIT_PULSE		(1  * JVC_UNIT)
+#define JVC_BIT_0_SPACE		(1  * JVC_UNIT)
+#define JVC_BIT_1_SPACE		(3  * JVC_UNIT)
+#define JVC_TRAILER_PULSE	(1  * JVC_UNIT)
+#define	JVC_TRAILER_SPACE	(35 * JVC_UNIT)
+
+/* Used to register jvc_decoder clients */
+static LIST_HEAD(decoder_list);
+DEFINE_SPINLOCK(decoder_lock);
+
+enum jvc_state {
+	STATE_INACTIVE,
+	STATE_HEADER_SPACE,
+	STATE_BIT_PULSE,
+	STATE_BIT_SPACE,
+	STATE_TRAILER_PULSE,
+	STATE_TRAILER_SPACE,
+};
+
+struct decoder_data {
+	struct list_head	list;
+	struct ir_input_dev	*ir_dev;
+	int			enabled:1;
+
+	/* State machine control */
+	enum jvc_state		state;
+	u16			jvc_bits;
+	u16			jvc_old_bits;
+	unsigned		count;
+	bool			first;
+	bool			toggle;
+};
+
+
+/**
+ * get_decoder_data()	- gets decoder data
+ * @input_dev:	input device
+ *
+ * Returns the struct decoder_data that corresponds to a device
+ */
+static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
+{
+	struct decoder_data *data = NULL;
+
+	spin_lock(&decoder_lock);
+	list_for_each_entry(data, &decoder_list, list) {
+		if (data->ir_dev == ir_dev)
+			break;
+	}
+	spin_unlock(&decoder_lock);
+	return data;
+}
+
+static ssize_t store_enabled(struct device *d,
+			     struct device_attribute *mattr,
+			     const char *buf,
+			     size_t len)
+{
+	unsigned long value;
+	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+	struct decoder_data *data = get_decoder_data(ir_dev);
+
+	if (!data)
+		return -EINVAL;
+
+	if (strict_strtoul(buf, 10, &value) || value > 1)
+		return -EINVAL;
+
+	data->enabled = value;
+
+	return len;
+}
+
+static ssize_t show_enabled(struct device *d,
+			     struct device_attribute *mattr, char *buf)
+{
+	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+	struct decoder_data *data = get_decoder_data(ir_dev);
+
+	if (!data)
+		return -EINVAL;
+
+	if (data->enabled)
+		return sprintf(buf, "1\n");
+	else
+	return sprintf(buf, "0\n");
+}
+
+static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
+
+static struct attribute *decoder_attributes[] = {
+	&dev_attr_enabled.attr,
+	NULL
+};
+
+static struct attribute_group decoder_attribute_group = {
+	.name	= "jvc_decoder",
+	.attrs	= decoder_attributes,
+};
+
+/**
+ * ir_jvc_decode() - Decode one JVC pulse or space
+ * @input_dev:	the struct input_dev descriptor of the device
+ * @duration:   the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This function returns -EINVAL if the pulse violates the state machine
+ */
+static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+{
+	struct decoder_data *data;
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+
+	data = get_decoder_data(ir_dev);
+	if (!data)
+		return -EINVAL;
+
+	if (!data->enabled)
+		return 0;
+
+	if (IS_RESET(ev)) {
+		data->state = STATE_INACTIVE;
+		return 0;
+	}
+
+	if (!geq_margin(ev.duration, JVC_UNIT, JVC_UNIT / 2))
+		goto out;
+
+	IR_dprintk(2, "JVC decode started at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+
+	switch (data->state) {
+
+	case STATE_INACTIVE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2))
+			break;
+
+		data->count = 0;
+		data->first = true;
+		data->toggle = !data->toggle;
+		data->state = STATE_HEADER_SPACE;
+		return 0;
+
+	case STATE_HEADER_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, JVC_HEADER_SPACE, JVC_UNIT / 2))
+			break;
+
+		data->state = STATE_BIT_PULSE;
+		return 0;
+
+	case STATE_BIT_PULSE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, JVC_BIT_PULSE, JVC_UNIT / 2))
+			break;
+
+		data->state = STATE_BIT_SPACE;
+		return 0;
+
+	case STATE_BIT_SPACE:
+		if (ev.pulse)
+			break;
+
+		data->jvc_bits <<= 1;
+		if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
+			data->jvc_bits |= 1;
+			decrease_duration(&ev, JVC_BIT_1_SPACE);
+		} else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
+			decrease_duration(&ev, JVC_BIT_0_SPACE);
+		else
+			break;
+		data->count++;
+
+		if (data->count == JVC_NBITS)
+			data->state = STATE_TRAILER_PULSE;
+		else
+			data->state = STATE_BIT_PULSE;
+		return 0;
+
+	case STATE_TRAILER_PULSE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, JVC_TRAILER_PULSE, JVC_UNIT / 2))
+			break;
+
+		data->state = STATE_TRAILER_SPACE;
+		return 0;
+
+	case STATE_TRAILER_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!geq_margin(ev.duration, JVC_TRAILER_SPACE, JVC_UNIT / 2))
+			break;
+
+		if (data->first) {
+			u32 scancode;
+			scancode = (bitrev8((data->jvc_bits >> 8) & 0xff) << 8) |
+				   (bitrev8((data->jvc_bits >> 0) & 0xff) << 0);
+			IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
+			ir_keydown(input_dev, scancode, data->toggle);
+			data->first = false;
+			data->jvc_old_bits = data->jvc_bits;
+		} else if (data->jvc_bits == data->jvc_old_bits) {
+			IR_dprintk(1, "JVC repeat\n");
+			ir_repeat(input_dev);
+		} else {
+			IR_dprintk(1, "JVC invalid repeat msg\n");
+			break;
+		}
+
+		data->count = 0;
+		data->state = STATE_BIT_PULSE;
+		return 0;
+	}
+
+out:
+	IR_dprintk(1, "JVC decode failed at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+	data->state = STATE_INACTIVE;
+	return -EINVAL;
+}
+
+static int ir_jvc_register(struct input_dev *input_dev)
+{
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+	struct decoder_data *data;
+	int rc;
+
+	rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
+	if (rc < 0)
+		return rc;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
+		return -ENOMEM;
+	}
+
+	data->ir_dev = ir_dev;
+	data->enabled = 1;
+
+	spin_lock(&decoder_lock);
+	list_add_tail(&data->list, &decoder_list);
+	spin_unlock(&decoder_lock);
+
+	return 0;
+}
+
+static int ir_jvc_unregister(struct input_dev *input_dev)
+{
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+	static struct decoder_data *data;
+
+	data = get_decoder_data(ir_dev);
+	if (!data)
+		return 0;
+
+	sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
+
+	spin_lock(&decoder_lock);
+	list_del(&data->list);
+	spin_unlock(&decoder_lock);
+
+	return 0;
+}
+
+static struct ir_raw_handler jvc_handler = {
+	.decode		= ir_jvc_decode,
+	.raw_register	= ir_jvc_register,
+	.raw_unregister	= ir_jvc_unregister,
+};
+
+static int __init ir_jvc_decode_init(void)
+{
+	ir_raw_handler_register(&jvc_handler);
+
+	printk(KERN_INFO "IR JVC protocol handler initialized\n");
+	return 0;
+}
+
+static void __exit ir_jvc_decode_exit(void)
+{
+	ir_raw_handler_unregister(&jvc_handler);
+}
+
+module_init(ir_jvc_decode_init);
+module_exit(ir_jvc_decode_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
+MODULE_DESCRIPTION("JVC IR protocol decoder");
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 59f173c..7eef6bf 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -233,6 +233,7 @@ static void init_decoders(struct work_struct *work)
 	load_nec_decode();
 	load_rc5_decode();
 	load_rc6_decode();
+	load_jvc_decode();
 
 	/* If needed, we may later add some init code. In this case,
 	   it is needed to change the CONFIG_MODULE test at ir-core.h
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index d7ec973..8e2751e 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -62,6 +62,8 @@ static ssize_t show_protocol(struct device *d,
 		s = "nec";
 	else if (ir_type == IR_TYPE_RC6)
 		s = "rc6";
+	else if (ir_type == IR_TYPE_JVC)
+		s = "jvc";
 	else
 		s = "other";
 
@@ -99,6 +101,8 @@ static ssize_t store_protocol(struct device *d,
 			ir_type |= IR_TYPE_PD;
 		if (!strcasecmp(buf, "nec"))
 			ir_type |= IR_TYPE_NEC;
+		if (!strcasecmp(buf, "jvc"))
+			ir_type |= IR_TYPE_JVC;
 	}
 
 	if (!ir_type) {
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 11f6618..214f072 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -16,6 +16,7 @@
 #define IR_TYPE_PD	(1  << 1)	/* Pulse distance encoded IR */
 #define IR_TYPE_NEC	(1  << 2)
 #define IR_TYPE_RC6	(1  << 3)	/* Philips RC6 protocol */
+#define IR_TYPE_JVC	(1  << 4)	/* JVC protocol */
 #define IR_TYPE_OTHER	(1u << 31)
 
 struct ir_scancode {

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3/8] ir-core: Add Sony support to ir-core
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
  2010-04-15 21:46   ` David Härdeman
  2010-04-15 21:46 ` [PATCH 2/8] ir-core: Add JVC support to ir-core David Härdeman
@ 2010-04-15 21:46 ` David Härdeman
  2010-04-15 21:46 ` [PATCH 4/8] ir-core: remove ir-functions usage from dm1105 David Härdeman
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

This patch adds a Sony12/15/20 decoder to ir-core.

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 drivers/media/IR/Kconfig           |    9 +
 drivers/media/IR/Makefile          |    1 
 drivers/media/IR/ir-core-priv.h    |    7 +
 drivers/media/IR/ir-raw-event.c    |    1 
 drivers/media/IR/ir-sony-decoder.c |  312 ++++++++++++++++++++++++++++++++++++
 drivers/media/IR/ir-sysfs.c        |    4 
 6 files changed, 334 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/IR/ir-sony-decoder.c

diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
index 179e4c3..25e10b5 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/IR/Kconfig
@@ -45,3 +45,12 @@ config IR_JVC_DECODER
 	---help---
 	   Enable this option if you have an infrared remote control which
 	   uses the JVC protocol, and you need software decoding support.
+
+config IR_SONY_DECODER
+	tristate "Enable IR raw decoder for the Sony protocol"
+	depends on IR_CORE
+	default y
+
+	---help---
+	   Enable this option if you have an infrared remote control which
+	   uses the Sony protocol, and you need software decoding support.
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
index 8d0098f..a12ee37 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/IR/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
 obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
 obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
 obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
+obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index 4b1a21d..04962a6 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -118,4 +118,11 @@ void ir_raw_init(void);
 #define load_jvc_decode()	0
 #endif
 
+/* from ir-sony-decoder.c */
+#ifdef CONFIG_IR_SONY_DECODER_MODULE
+#define load_sony_decode()	request_module("ir-sony-decoder")
+#else
+#define load_sony_decode()	0
+#endif
+
 #endif /* _IR_RAW_EVENT */
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 7eef6bf..ea68a3f 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -234,6 +234,7 @@ static void init_decoders(struct work_struct *work)
 	load_rc5_decode();
 	load_rc6_decode();
 	load_jvc_decode();
+	load_sony_decode();
 
 	/* If needed, we may later add some init code. In this case,
 	   it is needed to change the CONFIG_MODULE test at ir-core.h
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c
new file mode 100644
index 0000000..9f440c5
--- /dev/null
+++ b/drivers/media/IR/ir-sony-decoder.c
@@ -0,0 +1,312 @@
+/* ir-sony-decoder.c - handle Sony IR Pulse/Space protocol
+ *
+ * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bitrev.h>
+#include "ir-core-priv.h"
+
+#define SONY_UNIT		600000 /* ns */
+#define SONY_HEADER_PULSE	(4 * SONY_UNIT)
+#define	SONY_HEADER_SPACE	(1 * SONY_UNIT)
+#define SONY_BIT_0_PULSE	(1 * SONY_UNIT)
+#define SONY_BIT_1_PULSE	(2 * SONY_UNIT)
+#define SONY_BIT_SPACE		(1 * SONY_UNIT)
+#define SONY_TRAILER_SPACE	(10 * SONY_UNIT) /* minimum */
+
+/* Used to register sony_decoder clients */
+static LIST_HEAD(decoder_list);
+static DEFINE_SPINLOCK(decoder_lock);
+
+enum sony_state {
+	STATE_INACTIVE,
+	STATE_HEADER_SPACE,
+	STATE_BIT_PULSE,
+	STATE_BIT_SPACE,
+	STATE_FINISHED,
+};
+
+struct decoder_data {
+	struct list_head	list;
+	struct ir_input_dev	*ir_dev;
+	int			enabled:1;
+
+	/* State machine control */
+	enum sony_state		state;
+	u32			sony_bits;
+	unsigned		count;
+};
+
+
+/**
+ * get_decoder_data()	- gets decoder data
+ * @input_dev:	input device
+ *
+ * Returns the struct decoder_data that corresponds to a device
+ */
+static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
+{
+	struct decoder_data *data = NULL;
+
+	spin_lock(&decoder_lock);
+	list_for_each_entry(data, &decoder_list, list) {
+		if (data->ir_dev == ir_dev)
+			break;
+	}
+	spin_unlock(&decoder_lock);
+	return data;
+}
+
+static ssize_t store_enabled(struct device *d,
+			     struct device_attribute *mattr,
+			     const char *buf,
+			     size_t len)
+{
+	unsigned long value;
+	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+	struct decoder_data *data = get_decoder_data(ir_dev);
+
+	if (!data)
+		return -EINVAL;
+
+	if (strict_strtoul(buf, 10, &value) || value > 1)
+		return -EINVAL;
+
+	data->enabled = value;
+
+	return len;
+}
+
+static ssize_t show_enabled(struct device *d,
+			     struct device_attribute *mattr, char *buf)
+{
+	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+	struct decoder_data *data = get_decoder_data(ir_dev);
+
+	if (!data)
+		return -EINVAL;
+
+	if (data->enabled)
+		return sprintf(buf, "1\n");
+	else
+	return sprintf(buf, "0\n");
+}
+
+static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
+
+static struct attribute *decoder_attributes[] = {
+	&dev_attr_enabled.attr,
+	NULL
+};
+
+static struct attribute_group decoder_attribute_group = {
+	.name	= "sony_decoder",
+	.attrs	= decoder_attributes,
+};
+
+/**
+ * ir_sony_decode() - Decode one Sony pulse or space
+ * @input_dev:	the struct input_dev descriptor of the device
+ * @ev:         the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This function returns -EINVAL if the pulse violates the state machine
+ */
+static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+{
+	struct decoder_data *data;
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+	u32 scancode;
+	u8 device, subdevice, function;
+
+	data = get_decoder_data(ir_dev);
+	if (!data)
+		return -EINVAL;
+
+	if (!data->enabled)
+		return 0;
+
+	if (IS_RESET(ev)) {
+		data->state = STATE_INACTIVE;
+		return 0;
+	}
+
+	if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2))
+		goto out;
+
+	IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+
+	switch (data->state) {
+
+	case STATE_INACTIVE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2))
+			break;
+
+		data->count = 0;
+		data->state = STATE_HEADER_SPACE;
+		return 0;
+
+	case STATE_HEADER_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2))
+			break;
+
+		data->state = STATE_BIT_PULSE;
+		return 0;
+
+	case STATE_BIT_PULSE:
+		if (!ev.pulse)
+			break;
+
+		data->sony_bits <<= 1;
+		if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
+			data->sony_bits |= 1;
+		else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
+			break;
+
+		data->count++;
+		data->state = STATE_BIT_SPACE;
+		return 0;
+
+	case STATE_BIT_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2))
+			break;
+
+		decrease_duration(&ev, SONY_BIT_SPACE);
+
+		if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) {
+			data->state = STATE_BIT_PULSE;
+			return 0;
+		}
+
+		data->state = STATE_FINISHED;
+		/* Fall through */
+
+	case STATE_FINISHED:
+		if (ev.pulse)
+			break;
+
+		if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2))
+			break;
+
+		switch (data->count) {
+		case 12:
+			device    = bitrev8((data->sony_bits <<  3) & 0xF8);
+			subdevice = 0;
+			function  = bitrev8((data->sony_bits >>  4) & 0xFE);
+			break;
+		case 15:
+			device    = bitrev8((data->sony_bits >>  0) & 0xFF);
+			subdevice = 0;
+			function  = bitrev8((data->sony_bits >>  7) & 0xFD);
+			break;
+		case 20:
+			device    = bitrev8((data->sony_bits >>  5) & 0xF8);
+			subdevice = bitrev8((data->sony_bits >>  0) & 0xFF);
+			function  = bitrev8((data->sony_bits >> 12) & 0xFE);
+			break;
+		default:
+			IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
+			goto out;
+		}
+
+		scancode = device << 16 | subdevice << 8 | function;
+		IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode);
+		ir_keydown(input_dev, scancode, 0);
+		data->state = STATE_INACTIVE;
+		return 0;
+	}
+
+out:
+	IR_dprintk(1, "Sony decode failed at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+	data->state = STATE_INACTIVE;
+	return -EINVAL;
+}
+
+static int ir_sony_register(struct input_dev *input_dev)
+{
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+	struct decoder_data *data;
+	int rc;
+
+	rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
+	if (rc < 0)
+		return rc;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
+		return -ENOMEM;
+	}
+
+	data->ir_dev = ir_dev;
+	data->enabled = 1;
+
+	spin_lock(&decoder_lock);
+	list_add_tail(&data->list, &decoder_list);
+	spin_unlock(&decoder_lock);
+
+	return 0;
+}
+
+static int ir_sony_unregister(struct input_dev *input_dev)
+{
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+	static struct decoder_data *data;
+
+	data = get_decoder_data(ir_dev);
+	if (!data)
+		return 0;
+
+	sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
+
+	spin_lock(&decoder_lock);
+	list_del(&data->list);
+	spin_unlock(&decoder_lock);
+
+	return 0;
+}
+
+static struct ir_raw_handler sony_handler = {
+	.decode		= ir_sony_decode,
+	.raw_register	= ir_sony_register,
+	.raw_unregister	= ir_sony_unregister,
+};
+
+static int __init ir_sony_decode_init(void)
+{
+	ir_raw_handler_register(&sony_handler);
+
+	printk(KERN_INFO "IR Sony protocol handler initialized\n");
+	return 0;
+}
+
+static void __exit ir_sony_decode_exit(void)
+{
+	ir_raw_handler_unregister(&sony_handler);
+}
+
+module_init(ir_sony_decode_init);
+module_exit(ir_sony_decode_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
+MODULE_DESCRIPTION("Sony IR protocol decoder");
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index 8e2751e..dfd45fa 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -64,6 +64,8 @@ static ssize_t show_protocol(struct device *d,
 		s = "rc6";
 	else if (ir_type == IR_TYPE_JVC)
 		s = "jvc";
+	else if (ir_type == IR_TYPE_SONY)
+		s = "sony";
 	else
 		s = "other";
 
@@ -103,6 +105,8 @@ static ssize_t store_protocol(struct device *d,
 			ir_type |= IR_TYPE_NEC;
 		if (!strcasecmp(buf, "jvc"))
 			ir_type |= IR_TYPE_JVC;
+		if (!strcasecmp(buf, "sony"))
+			ir_type |= IR_TYPE_SONY;
 	}
 
 	if (!ir_type) {
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 214f072..67af24e 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -17,6 +17,7 @@
 #define IR_TYPE_NEC	(1  << 2)
 #define IR_TYPE_RC6	(1  << 3)	/* Philips RC6 protocol */
 #define IR_TYPE_JVC	(1  << 4)	/* JVC protocol */
+#define IR_TYPE_SONY	(1  << 5)	/* Sony12/15/20 protocol */
 #define IR_TYPE_OTHER	(1u << 31)
 
 struct ir_scancode {

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 4/8] ir-core: remove ir-functions usage from dm1105
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
                   ` (2 preceding siblings ...)
  2010-04-15 21:46 ` [PATCH 3/8] ir-core: Add Sony " David Härdeman
@ 2010-04-15 21:46 ` David Härdeman
  2010-04-15 21:46 ` [PATCH 5/8] ir-core: convert mantis from ir-functions.c David Härdeman
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

Convert drivers/media/dvb/dm1105/dm1105.c to not rely on
ir-functions.c.

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 0 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 333d7b1..89f1eca 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -27,7 +27,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/input.h>
-#include <media/ir-common.h>
+#include <media/ir-core.h>
 
 #include "demux.h"
 #include "dmxdev.h"
@@ -266,7 +266,6 @@ static void dm1105_card_list(struct pci_dev *pci)
 /* infrared remote control */
 struct infrared {
 	struct input_dev	*input_dev;
-	struct ir_input_state	ir;
 	char			input_phys[32];
 	struct work_struct	work;
 	u32			ir_command;
@@ -532,8 +531,7 @@ static void dm1105_emit_key(struct work_struct *work)
 
 	data = (ircom >> 8) & 0x7f;
 
-	ir_input_keydown(ir->input_dev, &ir->ir, data);
-	ir_input_nokey(ir->input_dev, &ir->ir);
+	ir_keydown(ir->input_dev, data, 0);
 }
 
 /* work handler */
@@ -596,7 +594,6 @@ int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
 {
 	struct input_dev *input_dev;
 	char *ir_codes = NULL;
-	u64 ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
 	input_dev = input_allocate_device();
@@ -607,12 +604,6 @@ int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
 	snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
 		"pci-%s/ir0", pci_name(dm1105->pdev));
 
-	err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type);
-	if (err < 0) {
-		input_free_device(input_dev);
-		return err;
-	}
-
 	input_dev->name = "DVB on-card IR receiver";
 	input_dev->phys = dm1105->ir.input_phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -630,8 +621,12 @@ int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
 	INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
 
 	err = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
+	if (err < 0) {
+		input_free_device(input_dev);
+		return err;
+	}
 
-	return err;
+	return 0;
 }
 
 void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 5/8] ir-core: convert mantis from ir-functions.c
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
                   ` (3 preceding siblings ...)
  2010-04-15 21:46 ` [PATCH 4/8] ir-core: remove ir-functions usage from dm1105 David Härdeman
@ 2010-04-15 21:46 ` David Härdeman
  2010-04-15 23:17     ` Manu Abraham
  2010-04-15 21:46   ` David Härdeman
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

Convert drivers/media/dvb/mantis/mantis_input.c to not use ir-functions.c
(The driver is anyway not complete enough to actually use the subsystem yet).

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 0 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
index 3d4e466..a99489b 100644
--- a/drivers/media/dvb/mantis/mantis_input.c
+++ b/drivers/media/dvb/mantis/mantis_input.c
@@ -19,7 +19,7 @@
 */
 
 #include <linux/input.h>
-#include <media/ir-common.h>
+#include <media/ir-core.h>
 #include <linux/pci.h>
 
 #include "dmxdev.h"
@@ -104,7 +104,6 @@ EXPORT_SYMBOL_GPL(ir_mantis);
 int mantis_input_init(struct mantis_pci *mantis)
 {
 	struct input_dev *rc;
-	struct ir_input_state rc_state;
 	char name[80], dev[80];
 	int err;
 
@@ -120,8 +119,6 @@ int mantis_input_init(struct mantis_pci *mantis)
 	rc->name = name;
 	rc->phys = dev;
 
-	ir_input_init(rc, &rc_state, IR_TYPE_OTHER);
-
 	rc->id.bustype	= BUS_PCI;
 	rc->id.vendor	= mantis->vendor_id;
 	rc->id.product	= mantis->device_id;

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 6/8] ir-core: fix double spinlock init in drivers/media/IR/rc-map.c
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
@ 2010-04-15 21:46   ` David Härdeman
  2010-04-15 21:46 ` [PATCH 2/8] ir-core: Add JVC support to ir-core David Härdeman
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

Fix a double initialization of the same spinlock in drivers/media/IR/rc-map.c.

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 drivers/media/IR/ir-sysfs.c |    2 --
 drivers/media/IR/rc-map.c   |    5 -----
 2 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index dfd45fa..876baae 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -294,8 +294,6 @@ static int __init ir_core_init(void)
 
 	/* Initialize/load the decoders/keymap code that will be used */
 	ir_raw_init();
-	rc_map_init();
-
 
 	return 0;
 }
diff --git a/drivers/media/IR/rc-map.c b/drivers/media/IR/rc-map.c
index 1a3f4b1..caf6a27 100644
--- a/drivers/media/IR/rc-map.c
+++ b/drivers/media/IR/rc-map.c
@@ -81,8 +81,3 @@ void ir_unregister_map(struct rc_keymap *map)
 }
 EXPORT_SYMBOL_GPL(ir_unregister_map);
 
-void rc_map_init(void)
-{
-	spin_lock_init(&rc_map_lock);
-
-}

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 6/8] ir-core: fix double spinlock init in drivers/media/IR/rc-map.c
@ 2010-04-15 21:46   ` David Härdeman
  0 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

Fix a double initialization of the same spinlock in drivers/media/IR/rc-map.c.

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 drivers/media/IR/ir-sysfs.c |    2 --
 drivers/media/IR/rc-map.c   |    5 -----
 2 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index dfd45fa..876baae 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -294,8 +294,6 @@ static int __init ir_core_init(void)
 
 	/* Initialize/load the decoders/keymap code that will be used */
 	ir_raw_init();
-	rc_map_init();
-
 
 	return 0;
 }
diff --git a/drivers/media/IR/rc-map.c b/drivers/media/IR/rc-map.c
index 1a3f4b1..caf6a27 100644
--- a/drivers/media/IR/rc-map.c
+++ b/drivers/media/IR/rc-map.c
@@ -81,8 +81,3 @@ void ir_unregister_map(struct rc_keymap *map)
 }
 EXPORT_SYMBOL_GPL(ir_unregister_map);
 
-void rc_map_init(void)
-{
-	spin_lock_init(&rc_map_lock);
-
-}


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 7/8] ir-core: fix table resize during keymap init
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
                   ` (5 preceding siblings ...)
  2010-04-15 21:46   ` David Härdeman
@ 2010-04-15 21:46 ` David Härdeman
  2010-04-15 21:46 ` [PATCH 8/8] ir-core: fix some confusing comments David Härdeman
  2010-04-15 21:59   ` David Härdeman
  8 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

drivers/media/IR/ir-keytable.c would alloc a suitably sized keymap table
only to have it resized as it is populated with the initial keymap.

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 drivers/media/IR/ir-keytable.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index 01bddc4..b8baf8f 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -77,6 +77,7 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab)
  * @rc_tab:	the struct ir_scancode_table to set the keycode in
  * @scancode:	the scancode for the ir command
  * @keycode:	the keycode for the ir command
+ * @resize:	whether the keytable may be shrunk
  * @return:	-EINVAL if the keycode could not be inserted, otherwise zero.
  *
  * This routine is used internally to manipulate the scancode->keycode table.
@@ -84,7 +85,8 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab)
  */
 static int ir_do_setkeycode(struct input_dev *dev,
 			    struct ir_scancode_table *rc_tab,
-			    int scancode, int keycode)
+			    int scancode, int keycode,
+			    bool resize)
 {
 	unsigned int i;
 	int old_keycode = KEY_RESERVED;
@@ -128,7 +130,7 @@ static int ir_do_setkeycode(struct input_dev *dev,
 
 	if (old_keycode == KEY_RESERVED) {
 		/* No previous mapping found, we might need to grow the table */
-		if (ir_resize_table(rc_tab))
+		if (resize && ir_resize_table(rc_tab))
 			return -ENOMEM;
 
 		IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
@@ -176,7 +178,7 @@ static int ir_setkeycode(struct input_dev *dev,
 	struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
 
 	spin_lock_irqsave(&rc_tab->lock, flags);
-	rc = ir_do_setkeycode(dev, rc_tab, scancode, keycode);
+	rc = ir_do_setkeycode(dev, rc_tab, scancode, keycode, true);
 	spin_unlock_irqrestore(&rc_tab->lock, flags);
 	return rc;
 }
@@ -203,7 +205,7 @@ static int ir_setkeytable(struct input_dev *dev,
 	spin_lock_irqsave(&rc_tab->lock, flags);
 	for (i = 0; i < from->size; i++) {
 		rc = ir_do_setkeycode(dev, to, from->scan[i].scancode,
-				      from->scan[i].keycode);
+				      from->scan[i].keycode, false);
 		if (rc)
 			break;
 	}

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 8/8] ir-core: fix some confusing comments
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
                   ` (6 preceding siblings ...)
  2010-04-15 21:46 ` [PATCH 7/8] ir-core: fix table resize during keymap init David Härdeman
@ 2010-04-15 21:46 ` David Härdeman
  2010-04-15 21:59   ` David Härdeman
  8 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:46 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

Fix some confusing comments in drivers/media/IR/*

Signed-off-by: David Härdeman <david@hardeman.nu>
---
 drivers/media/IR/ir-keytable.c |    2 +-
 drivers/media/IR/ir-sysfs.c    |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index b8baf8f..de923fc 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -1,4 +1,4 @@
-/* ir-register.c - handle IR scancode->keycode tables
+/* ir-keytable.c - handle IR scancode->keycode tables
  *
  * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
  *
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index 876baae..501dc2f 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -1,4 +1,4 @@
-/* ir-register.c - handle IR scancode->keycode tables
+/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc)
  *
  * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
  *

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/8] Series short description
  2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
@ 2010-04-15 21:59   ` David Härdeman
  2010-04-15 21:46 ` [PATCH 2/8] ir-core: Add JVC support to ir-core David Härdeman
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:59 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

On Thu, Apr 15, 2010 at 11:45:55PM +0200, David Härdeman wrote:
> The following series implements the suggested change to ir-core
> to use a 1:31 struct for pulse/space durations, adds two new
> raw decoders, converts two users of ir-functions to plain ir-core
> and fixes a few small bugs in ir-core.

Sorry about the subject of this mail...missed filling in that field :)

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/8] Series short description
@ 2010-04-15 21:59   ` David Härdeman
  0 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-15 21:59 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media, linux-input

On Thu, Apr 15, 2010 at 11:45:55PM +0200, David Härdeman wrote:
> The following series implements the suggested change to ir-core
> to use a 1:31 struct for pulse/space durations, adds two new
> raw decoders, converts two users of ir-functions to plain ir-core
> and fixes a few small bugs in ir-core.

Sorry about the subject of this mail...missed filling in that field :)


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] ir-core: convert mantis from ir-functions.c
  2010-04-15 21:46 ` [PATCH 5/8] ir-core: convert mantis from ir-functions.c David Härdeman
@ 2010-04-15 23:17     ` Manu Abraham
  0 siblings, 0 replies; 30+ messages in thread
From: Manu Abraham @ 2010-04-15 23:17 UTC (permalink / raw)
  To: David Härdeman; +Cc: mchehab, linux-media, linux-input

On Fri, Apr 16, 2010 at 1:46 AM, David Härdeman <david@hardeman.nu> wrote:
> Convert drivers/media/dvb/mantis/mantis_input.c to not use ir-functions.c
> (The driver is anyway not complete enough to actually use the subsystem yet).

Huh ? I don't follow what you imply here ..
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] ir-core: convert mantis from ir-functions.c
@ 2010-04-15 23:17     ` Manu Abraham
  0 siblings, 0 replies; 30+ messages in thread
From: Manu Abraham @ 2010-04-15 23:17 UTC (permalink / raw)
  To: David Härdeman; +Cc: mchehab, linux-media, linux-input

On Fri, Apr 16, 2010 at 1:46 AM, David Härdeman <david@hardeman.nu> wrote:
> Convert drivers/media/dvb/mantis/mantis_input.c to not use ir-functions.c
> (The driver is anyway not complete enough to actually use the subsystem yet).

Huh ? I don't follow what you imply here ..

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] ir-core: convert mantis from ir-functions.c
  2010-04-15 23:17     ` Manu Abraham
  (?)
@ 2010-04-16 20:56     ` David Härdeman
  2010-04-16 21:27         ` Manu Abraham
  -1 siblings, 1 reply; 30+ messages in thread
From: David Härdeman @ 2010-04-16 20:56 UTC (permalink / raw)
  To: Manu Abraham; +Cc: mchehab, linux-media, linux-input

On Fri, Apr 16, 2010 at 03:17:35AM +0400, Manu Abraham wrote:
> On Fri, Apr 16, 2010 at 1:46 AM, David Härdeman <david@hardeman.nu> wrote:
> > Convert drivers/media/dvb/mantis/mantis_input.c to not use ir-functions.c
> > (The driver is anyway not complete enough to actually use the subsystem yet).
> 
> Huh ? I don't follow what you imply here ..
> 

The mantis_input.c file seems to be a skeleton as far as I could 
tell...not actually in use yet. Or am I mistaken?

-- 
David Härdeman

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] ir-core: convert mantis from ir-functions.c
  2010-04-16 20:56     ` David Härdeman
@ 2010-04-16 21:27         ` Manu Abraham
  0 siblings, 0 replies; 30+ messages in thread
From: Manu Abraham @ 2010-04-16 21:27 UTC (permalink / raw)
  To: David Härdeman; +Cc: mchehab, linux-media, linux-input

On Sat, Apr 17, 2010 at 12:56 AM, David Härdeman <david@hardeman.nu> wrote:
> On Fri, Apr 16, 2010 at 03:17:35AM +0400, Manu Abraham wrote:
>> On Fri, Apr 16, 2010 at 1:46 AM, David Härdeman <david@hardeman.nu> wrote:
>> > Convert drivers/media/dvb/mantis/mantis_input.c to not use ir-functions.c
>> > (The driver is anyway not complete enough to actually use the subsystem yet).
>>
>> Huh ? I don't follow what you imply here ..
>>
>
> The mantis_input.c file seems to be a skeleton as far as I could
> tell...not actually in use yet. Or am I mistaken?

Only the input related parts of the IR stuff is there in
mantis_input.c, the hardware handling is done by mantis_uart.c/h.
There is a small bit which has not gone upstream yet, which is
pending;
http://jusst.de/hg/mantis-v4l-dvb/rev/ad8b00c9edc2
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] ir-core: convert mantis from ir-functions.c
@ 2010-04-16 21:27         ` Manu Abraham
  0 siblings, 0 replies; 30+ messages in thread
From: Manu Abraham @ 2010-04-16 21:27 UTC (permalink / raw)
  To: David Härdeman; +Cc: mchehab, linux-media, linux-input

On Sat, Apr 17, 2010 at 12:56 AM, David Härdeman <david@hardeman.nu> wrote:
> On Fri, Apr 16, 2010 at 03:17:35AM +0400, Manu Abraham wrote:
>> On Fri, Apr 16, 2010 at 1:46 AM, David Härdeman <david@hardeman.nu> wrote:
>> > Convert drivers/media/dvb/mantis/mantis_input.c to not use ir-functions.c
>> > (The driver is anyway not complete enough to actually use the subsystem yet).
>>
>> Huh ? I don't follow what you imply here ..
>>
>
> The mantis_input.c file seems to be a skeleton as far as I could
> tell...not actually in use yet. Or am I mistaken?

Only the input related parts of the IR stuff is there in
mantis_input.c, the hardware handling is done by mantis_uart.c/h.
There is a small bit which has not gone upstream yet, which is
pending;
http://jusst.de/hg/mantis-v4l-dvb/rev/ad8b00c9edc2

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] ir-core: convert mantis from ir-functions.c
  2010-04-16 21:27         ` Manu Abraham
@ 2010-04-19  9:58           ` David Härdeman
  -1 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-19  9:58 UTC (permalink / raw)
  To: Manu Abraham; +Cc: mchehab, linux-media, linux-input

On Sat, Apr 17, 2010 at 01:27:05AM +0400, Manu Abraham wrote:
> On Sat, Apr 17, 2010 at 12:56 AM, David Härdeman <david@hardeman.nu> wrote:
> > On Fri, Apr 16, 2010 at 03:17:35AM +0400, Manu Abraham wrote:
> >> On Fri, Apr 16, 2010 at 1:46 AM, David Härdeman <david@hardeman.nu> wrote:
> >> > Convert drivers/media/dvb/mantis/mantis_input.c to not use ir-functions.c
> >> > (The driver is anyway not complete enough to actually use the subsystem yet).
> >>
> >> Huh ? I don't follow what you imply here ..
> >>
> >
> > The mantis_input.c file seems to be a skeleton as far as I could
> > tell...not actually in use yet. Or am I mistaken?
> 
> Only the input related parts of the IR stuff is there in
> mantis_input.c, the hardware handling is done by mantis_uart.c/h.
> There is a small bit which has not gone upstream yet, which is
> pending;
> http://jusst.de/hg/mantis-v4l-dvb/rev/ad8b00c9edc2
> 

Yes, and that patch includes actually calling mantis_input_init(), which 
wasn't called previously, so mantis_input.c wasn't actually in use.

Anyways, my patch still applies (or the principle at least) - use the 
functionality of ir-core and not ir-functions.c (which is going away).

And on a related note, the above patch adds keytables with entries like 
KEY_0, they should probably be KEY_NUMERIC_* instead.

-- 
David Härdeman
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] ir-core: convert mantis from ir-functions.c
@ 2010-04-19  9:58           ` David Härdeman
  0 siblings, 0 replies; 30+ messages in thread
From: David Härdeman @ 2010-04-19  9:58 UTC (permalink / raw)
  To: Manu Abraham; +Cc: mchehab, linux-media, linux-input

On Sat, Apr 17, 2010 at 01:27:05AM +0400, Manu Abraham wrote:
> On Sat, Apr 17, 2010 at 12:56 AM, David Härdeman <david@hardeman.nu> wrote:
> > On Fri, Apr 16, 2010 at 03:17:35AM +0400, Manu Abraham wrote:
> >> On Fri, Apr 16, 2010 at 1:46 AM, David Härdeman <david@hardeman.nu> wrote:
> >> > Convert drivers/media/dvb/mantis/mantis_input.c to not use ir-functions.c
> >> > (The driver is anyway not complete enough to actually use the subsystem yet).
> >>
> >> Huh ? I don't follow what you imply here ..
> >>
> >
> > The mantis_input.c file seems to be a skeleton as far as I could
> > tell...not actually in use yet. Or am I mistaken?
> 
> Only the input related parts of the IR stuff is there in
> mantis_input.c, the hardware handling is done by mantis_uart.c/h.
> There is a small bit which has not gone upstream yet, which is
> pending;
> http://jusst.de/hg/mantis-v4l-dvb/rev/ad8b00c9edc2
> 

Yes, and that patch includes actually calling mantis_input_init(), which 
wasn't called previously, so mantis_input.c wasn't actually in use.

Anyways, my patch still applies (or the principle at least) - use the 
functionality of ir-core and not ir-functions.c (which is going away).

And on a related note, the above patch adds keytables with entries like 
KEY_0, they should probably be KEY_NUMERIC_* instead.

-- 
David Härdeman

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2010-04-19  9:58 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-15 21:45 [PATCH 0/8] Series short description David Härdeman
2010-04-15 21:46 ` [PATCH 1/8] ir-core: change duration to be coded as a u32 integer David Härdeman
2010-04-15 21:46   ` David Härdeman
2010-04-15 21:46 ` [PATCH 2/8] ir-core: Add JVC support to ir-core David Härdeman
2010-04-15 21:46 ` [PATCH 3/8] ir-core: Add Sony " David Härdeman
2010-04-15 21:46 ` [PATCH 4/8] ir-core: remove ir-functions usage from dm1105 David Härdeman
2010-04-15 21:46 ` [PATCH 5/8] ir-core: convert mantis from ir-functions.c David Härdeman
2010-04-15 23:17   ` Manu Abraham
2010-04-15 23:17     ` Manu Abraham
2010-04-16 20:56     ` David Härdeman
2010-04-16 21:27       ` Manu Abraham
2010-04-16 21:27         ` Manu Abraham
2010-04-19  9:58         ` David Härdeman
2010-04-19  9:58           ` David Härdeman
2010-04-15 21:46 ` [PATCH 6/8] ir-core: fix double spinlock init in drivers/media/IR/rc-map.c David Härdeman
2010-04-15 21:46   ` David Härdeman
2010-04-15 21:46 ` [PATCH 7/8] ir-core: fix table resize during keymap init David Härdeman
2010-04-15 21:46 ` [PATCH 8/8] ir-core: fix some confusing comments David Härdeman
2010-04-15 21:59 ` [PATCH 0/8] Series short description David Härdeman
2010-04-15 21:59   ` David Härdeman
  -- strict thread matches above, loose matches on Subject: below --
2009-11-26  0:18 Tony Lindgren
2009-11-26  0:18 ` Tony Lindgren
2009-11-26  6:44 ` Hemanth V
2009-11-26  6:44   ` Hemanth V
2009-11-26  8:27   ` Tony Lindgren
2009-11-26  8:27     ` Tony Lindgren
2009-11-29 10:03 ` Shilimkar, Santosh
2009-11-29 10:03   ` Shilimkar, Santosh
2009-05-01 16:36 Chuck Lever
2009-01-15 13:29 Alan Cox

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.