RE: [PATCH] rc: img-ir: Add and enable sys clock for IR

2015-04-09 Thread Sifan Naeem
Hi Mauro,

Seems like you have applied the correct patch after all. ([v2] rc: img-ir: Add 
and enable sys clock for img-ir)

Thanks,
Sifan

 -Original Message-
 From: Mauro Carvalho Chehab [mailto:mche...@osg.samsung.com]
 Sent: 08 April 2015 15:41
 To: Sifan Naeem
 Cc: James Hogan; linux-ker...@vger.kernel.org; linux-
 me...@vger.kernel.org
 Subject: Re: [PATCH] rc: img-ir: Add and enable sys clock for IR
 
 Em Wed, 08 Apr 2015 13:56:14 +
 Sifan Naeem sifan.na...@imgtec.com escreveu:
 
  Hi Mauro,
 
  I sent you a v2 of this patch on 4th February:
 
  From: Sifan Naeem
  Sent: 04 February 2015 16:48
  To: James Hogan; mche...@osg.samsung.com
  Cc: linux-ker...@vger.kernel.org; linux-media@vger.kernel.org; Sifan
  Naeem
  Subject: [PATCH v2] rc: img-ir: Add and enable sys clock for img-ir
 
 
  Unfortunately, while trying to improve the commit message in v2 I had
 changed the last word of the patch name from IR to img-ir.
 
  Do you want me to do a diff between the 2 patches and send you a new
 patch?
 
 Yes, please do that, changing the patch name/description to reflect what
 changed since v1.
 
 Regards,
 Mauro
 
 
  Sifan
 
   -Original Message-
   From: Mauro Carvalho Chehab [mailto:mche...@osg.samsung.com]
   Sent: 08 April 2015 12:32
   To: Sifan Naeem
   Cc: James Hogan; linux-ker...@vger.kernel.org; linux-
   me...@vger.kernel.org
   Subject: Re: [PATCH] rc: img-ir: Add and enable sys clock for IR
  
   Em Tue, 3 Feb 2015 17:30:29 +
   Sifan Naeem sifan.na...@imgtec.com escreveu:
  
Gets a handle to the system clock, already described in the
binding document, and calls the appropriate common clock framework
functions to mark it prepared/enabled, the common clock framework
initially enables the clock and doesn't disable it at least until
the device/driver is removed.
The system clock to IR is needed for the driver to communicate
with the IR hardware via MMIO accesses on the system bus, so it
must not be disabled during use or the driver will malfunction.
  
   Hmm... patchwork has two versions of this patch, but I have only one
   on my e-mail.
  
   Could you please check if I applied the right one? If not, please
   send me an email with a fixup patch.
  
   Thanks!
   Mauro
  
   
Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/img-ir-core.c |   13 +
 drivers/media/rc/img-ir/img-ir.h  |2 ++
 2 files changed, 11 insertions(+), 4 deletions(-)
   
diff --git a/drivers/media/rc/img-ir/img-ir-core.c
b/drivers/media/rc/img-ir/img-ir-core.c
index 77c78de..783dd21 100644
--- a/drivers/media/rc/img-ir/img-ir-core.c
+++ b/drivers/media/rc/img-ir/img-ir-core.c
@@ -60,6 +60,8 @@ static void img_ir_setup(struct img_ir_priv
*priv)
   
if (!IS_ERR(priv-clk))
clk_prepare_enable(priv-clk);
+   if (!IS_ERR(priv-sys_clk))
+   clk_prepare_enable(priv-sys_clk);
 }
   
 static void img_ir_ident(struct img_ir_priv *priv) @@ -110,10
+112,11 @@ static int img_ir_probe(struct platform_device *pdev)
priv-clk = devm_clk_get(pdev-dev, core);
if (IS_ERR(priv-clk))
dev_warn(pdev-dev, cannot get core clock 
resource\n);
-   /*
-* The driver doesn't need to know about the system (sys) or
   power
-* modulation (mod) clocks yet
-*/
+
+   /* Get sys clock */
+   priv-sys_clk = devm_clk_get(pdev-dev, sys);
+   if (IS_ERR(priv-sys_clk))
+   dev_warn(pdev-dev, cannot get sys clock resource\n);
   
/* Set up raw  hw decoder */
error = img_ir_probe_raw(priv);
@@ -152,6 +155,8 @@ static int img_ir_remove(struct
platform_device
*pdev)
   
if (!IS_ERR(priv-clk))
clk_disable_unprepare(priv-clk);
+   if (!IS_ERR(priv-sys_clk))
+   clk_disable_unprepare(priv-sys_clk);
return 0;
 }
   
diff --git a/drivers/media/rc/img-ir/img-ir.h
b/drivers/media/rc/img-ir/img-ir.h
index 2ddf560..f1387c0 100644
--- a/drivers/media/rc/img-ir/img-ir.h
+++ b/drivers/media/rc/img-ir/img-ir.h
@@ -138,6 +138,7 @@ struct clk;
  * @dev:   Platform device.
  * @irq:   IRQ number.
  * @clk:   Input clock.
+ * @sys_clk:   System clock.
  * @reg_base:  Iomem base address of IR register block.
  * @lock:  Protects IR registers and variables in this 
struct.
  * @raw:   Driver data for raw decoder.
@@ -147,6 +148,7 @@ struct img_ir_priv {
struct device   *dev;
int irq;
struct clk  *clk;
+   struct clk  *sys_clk;
void __iomem*reg_base;
spinlock_t

RE: [PATCH] rc: img-ir: Add and enable sys clock for IR

2015-04-08 Thread Sifan Naeem
Hi Mauro,

I sent you a v2 of this patch on 4th February:

From: Sifan Naeem 
Sent: 04 February 2015 16:48
To: James Hogan; mche...@osg.samsung.com
Cc: linux-ker...@vger.kernel.org; linux-media@vger.kernel.org; Sifan Naeem
Subject: [PATCH v2] rc: img-ir: Add and enable sys clock for img-ir


Unfortunately, while trying to improve the commit message in v2 I had changed 
the last word of the patch name from IR to img-ir.

Do you want me to do a diff between the 2 patches and send you a new patch?

Sifan

 -Original Message-
 From: Mauro Carvalho Chehab [mailto:mche...@osg.samsung.com]
 Sent: 08 April 2015 12:32
 To: Sifan Naeem
 Cc: James Hogan; linux-ker...@vger.kernel.org; linux-
 me...@vger.kernel.org
 Subject: Re: [PATCH] rc: img-ir: Add and enable sys clock for IR
 
 Em Tue, 3 Feb 2015 17:30:29 +
 Sifan Naeem sifan.na...@imgtec.com escreveu:
 
  Gets a handle to the system clock, already described in the binding
  document, and calls the appropriate common clock framework functions
  to mark it prepared/enabled, the common clock framework initially
  enables the clock and doesn't disable it at least until the
  device/driver is removed.
  The system clock to IR is needed for the driver to communicate with
  the IR hardware via MMIO accesses on the system bus, so it must not be
  disabled during use or the driver will malfunction.
 
 Hmm... patchwork has two versions of this patch, but I have only one on my
 e-mail.
 
 Could you please check if I applied the right one? If not, please send me an
 email with a fixup patch.
 
 Thanks!
 Mauro
 
 
  Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
  ---
   drivers/media/rc/img-ir/img-ir-core.c |   13 +
   drivers/media/rc/img-ir/img-ir.h  |2 ++
   2 files changed, 11 insertions(+), 4 deletions(-)
 
  diff --git a/drivers/media/rc/img-ir/img-ir-core.c
  b/drivers/media/rc/img-ir/img-ir-core.c
  index 77c78de..783dd21 100644
  --- a/drivers/media/rc/img-ir/img-ir-core.c
  +++ b/drivers/media/rc/img-ir/img-ir-core.c
  @@ -60,6 +60,8 @@ static void img_ir_setup(struct img_ir_priv *priv)
 
  if (!IS_ERR(priv-clk))
  clk_prepare_enable(priv-clk);
  +   if (!IS_ERR(priv-sys_clk))
  +   clk_prepare_enable(priv-sys_clk);
   }
 
   static void img_ir_ident(struct img_ir_priv *priv) @@ -110,10 +112,11
  @@ static int img_ir_probe(struct platform_device *pdev)
  priv-clk = devm_clk_get(pdev-dev, core);
  if (IS_ERR(priv-clk))
  dev_warn(pdev-dev, cannot get core clock resource\n);
  -   /*
  -* The driver doesn't need to know about the system (sys) or
 power
  -* modulation (mod) clocks yet
  -*/
  +
  +   /* Get sys clock */
  +   priv-sys_clk = devm_clk_get(pdev-dev, sys);
  +   if (IS_ERR(priv-sys_clk))
  +   dev_warn(pdev-dev, cannot get sys clock resource\n);
 
  /* Set up raw  hw decoder */
  error = img_ir_probe_raw(priv);
  @@ -152,6 +155,8 @@ static int img_ir_remove(struct platform_device
  *pdev)
 
  if (!IS_ERR(priv-clk))
  clk_disable_unprepare(priv-clk);
  +   if (!IS_ERR(priv-sys_clk))
  +   clk_disable_unprepare(priv-sys_clk);
  return 0;
   }
 
  diff --git a/drivers/media/rc/img-ir/img-ir.h
  b/drivers/media/rc/img-ir/img-ir.h
  index 2ddf560..f1387c0 100644
  --- a/drivers/media/rc/img-ir/img-ir.h
  +++ b/drivers/media/rc/img-ir/img-ir.h
  @@ -138,6 +138,7 @@ struct clk;
* @dev:   Platform device.
* @irq:   IRQ number.
* @clk:   Input clock.
  + * @sys_clk:   System clock.
* @reg_base:  Iomem base address of IR register block.
* @lock:  Protects IR registers and variables in this struct.
* @raw:   Driver data for raw decoder.
  @@ -147,6 +148,7 @@ struct img_ir_priv {
  struct device   *dev;
  int irq;
  struct clk  *clk;
  +   struct clk  *sys_clk;
  void __iomem*reg_base;
  spinlock_t  lock;
 
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] rc: img-ir: fix error in parameters passed to irq_free()

2015-02-10 Thread Sifan Naeem
img_ir_remove() passes a pointer to the ISR function as the 2nd
parameter to irq_free() instead of a pointer to the device data
structure.
This issue causes unloading img-ir module to fail with the below
warning after building and loading img-ir as a module.

WARNING: CPU: 2 PID: 155 at ../kernel/irq/manage.c:1278
__free_irq+0xb4/0x214() Trying to free already-free IRQ 58
Modules linked in: img_ir(-)
CPU: 2 PID: 155 Comm: rmmod Not tainted 3.14.0 #55 ...
Call Trace:
...
[8048d420] __free_irq+0xb4/0x214
[8048d6b4] free_irq+0xac/0xf4
[c009b130] img_ir_remove+0x54/0xd4 [img_ir] [8073ded0]
platform_drv_remove+0x30/0x54 ...

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
Fixes: 160a8f8aec4d ([media] rc: img-ir: add base driver)
Cc: sta...@vger.kernel.org # 3.15+
---
 drivers/media/rc/img-ir/img-ir-core.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/rc/img-ir/img-ir-core.c 
b/drivers/media/rc/img-ir/img-ir-core.c
index 77c78de..7020659 100644
--- a/drivers/media/rc/img-ir/img-ir-core.c
+++ b/drivers/media/rc/img-ir/img-ir-core.c
@@ -146,7 +146,7 @@ static int img_ir_remove(struct platform_device *pdev)
 {
struct img_ir_priv *priv = platform_get_drvdata(pdev);
 
-   free_irq(priv-irq, img_ir_isr);
+   free_irq(priv-irq, priv);
img_ir_remove_hw(priv);
img_ir_remove_raw(priv);
 
-- 
1.7.9.5

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


[PATCH v2] rc: img-ir: Add and enable sys clock for img-ir

2015-02-04 Thread Sifan Naeem
Gets a handle to the system clock, already described in the binding
document, and calls the appropriate common clock framework functions
to mark it prepared/enabled, the common clock framework initially
enables the clock and doesn't disable it at least until the
device/driver is removed.
It's important the systen clock is enabled before register interface is
accessed by the driver.
The system clock to IR is needed for the driver to communicate with the
IR hardware via MMIO accesses on the system bus, so it must not be
disabled during use or the driver will malfunction.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
Changes from v1:
System clock enabled in probe function before any hardware is accessed.
Error handling in probe function ensures ISR doesn't get called with 
system clock disabled.

 drivers/media/rc/img-ir/img-ir-core.c |   29 +
 drivers/media/rc/img-ir/img-ir.h  |2 ++
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/media/rc/img-ir/img-ir-core.c 
b/drivers/media/rc/img-ir/img-ir-core.c
index 77c78de..a10d666 100644
--- a/drivers/media/rc/img-ir/img-ir-core.c
+++ b/drivers/media/rc/img-ir/img-ir-core.c
@@ -110,16 +110,32 @@ static int img_ir_probe(struct platform_device *pdev)
priv-clk = devm_clk_get(pdev-dev, core);
if (IS_ERR(priv-clk))
dev_warn(pdev-dev, cannot get core clock resource\n);
+
+   /* Get sys clock */
+   priv-sys_clk = devm_clk_get(pdev-dev, sys);
+   if (IS_ERR(priv-sys_clk))
+   dev_warn(pdev-dev, cannot get sys clock resource\n);
/*
-* The driver doesn't need to know about the system (sys) or power
-* modulation (mod) clocks yet
+* Enabling the system clock before the register interface is
+* accessed. ISR shouldn't get called with Sys Clock disabled,
+* hence exiting probe with an error.
 */
+   if (!IS_ERR(priv-sys_clk)) {
+   error = clk_prepare_enable(priv-sys_clk);
+   if (error) {
+   dev_err(pdev-dev, cannot enable sys clock\n);
+   return error;
+   }
+   }
 
/* Set up raw  hw decoder */
error = img_ir_probe_raw(priv);
error2 = img_ir_probe_hw(priv);
-   if (error  error2)
-   return (error == -ENODEV) ? error2 : error;
+   if (error  error2) {
+   if (error == -ENODEV)
+   error = error2;
+   goto err_probe;
+   }
 
/* Get the IRQ */
priv-irq = irq;
@@ -139,6 +155,9 @@ static int img_ir_probe(struct platform_device *pdev)
 err_irq:
img_ir_remove_hw(priv);
img_ir_remove_raw(priv);
+err_probe:
+   if (!IS_ERR(priv-sys_clk))
+   clk_disable_unprepare(priv-sys_clk);
return error;
 }
 
@@ -152,6 +171,8 @@ static int img_ir_remove(struct platform_device *pdev)
 
if (!IS_ERR(priv-clk))
clk_disable_unprepare(priv-clk);
+   if (!IS_ERR(priv-sys_clk))
+   clk_disable_unprepare(priv-sys_clk);
return 0;
 }
 
diff --git a/drivers/media/rc/img-ir/img-ir.h b/drivers/media/rc/img-ir/img-ir.h
index 2ddf560..f1387c0 100644
--- a/drivers/media/rc/img-ir/img-ir.h
+++ b/drivers/media/rc/img-ir/img-ir.h
@@ -138,6 +138,7 @@ struct clk;
  * @dev:   Platform device.
  * @irq:   IRQ number.
  * @clk:   Input clock.
+ * @sys_clk:   System clock.
  * @reg_base:  Iomem base address of IR register block.
  * @lock:  Protects IR registers and variables in this struct.
  * @raw:   Driver data for raw decoder.
@@ -147,6 +148,7 @@ struct img_ir_priv {
struct device   *dev;
int irq;
struct clk  *clk;
+   struct clk  *sys_clk;
void __iomem*reg_base;
spinlock_t  lock;
 
-- 
1.7.9.5

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


[PATCH] rc: img-ir: Add and enable sys clock for IR

2015-02-03 Thread Sifan Naeem
Gets a handle to the system clock, already described in the binding
document, and calls the appropriate common clock
framework functions to mark it prepared/enabled, the common clock
framework initially enables the clock and doesn't disable it at least
until the device/driver is removed.
The system clock to IR is needed for the driver to communicate with the
IR hardware via MMIO accesses on the system bus, so it must not be
disabled during use or the driver will malfunction.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/img-ir-core.c |   13 +
 drivers/media/rc/img-ir/img-ir.h  |2 ++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/media/rc/img-ir/img-ir-core.c 
b/drivers/media/rc/img-ir/img-ir-core.c
index 77c78de..783dd21 100644
--- a/drivers/media/rc/img-ir/img-ir-core.c
+++ b/drivers/media/rc/img-ir/img-ir-core.c
@@ -60,6 +60,8 @@ static void img_ir_setup(struct img_ir_priv *priv)
 
if (!IS_ERR(priv-clk))
clk_prepare_enable(priv-clk);
+   if (!IS_ERR(priv-sys_clk))
+   clk_prepare_enable(priv-sys_clk);
 }
 
 static void img_ir_ident(struct img_ir_priv *priv)
@@ -110,10 +112,11 @@ static int img_ir_probe(struct platform_device *pdev)
priv-clk = devm_clk_get(pdev-dev, core);
if (IS_ERR(priv-clk))
dev_warn(pdev-dev, cannot get core clock resource\n);
-   /*
-* The driver doesn't need to know about the system (sys) or power
-* modulation (mod) clocks yet
-*/
+
+   /* Get sys clock */
+   priv-sys_clk = devm_clk_get(pdev-dev, sys);
+   if (IS_ERR(priv-sys_clk))
+   dev_warn(pdev-dev, cannot get sys clock resource\n);
 
/* Set up raw  hw decoder */
error = img_ir_probe_raw(priv);
@@ -152,6 +155,8 @@ static int img_ir_remove(struct platform_device *pdev)
 
if (!IS_ERR(priv-clk))
clk_disable_unprepare(priv-clk);
+   if (!IS_ERR(priv-sys_clk))
+   clk_disable_unprepare(priv-sys_clk);
return 0;
 }
 
diff --git a/drivers/media/rc/img-ir/img-ir.h b/drivers/media/rc/img-ir/img-ir.h
index 2ddf560..f1387c0 100644
--- a/drivers/media/rc/img-ir/img-ir.h
+++ b/drivers/media/rc/img-ir/img-ir.h
@@ -138,6 +138,7 @@ struct clk;
  * @dev:   Platform device.
  * @irq:   IRQ number.
  * @clk:   Input clock.
+ * @sys_clk:   System clock.
  * @reg_base:  Iomem base address of IR register block.
  * @lock:  Protects IR registers and variables in this struct.
  * @raw:   Driver data for raw decoder.
@@ -147,6 +148,7 @@ struct img_ir_priv {
struct device   *dev;
int irq;
struct clk  *clk;
+   struct clk  *sys_clk;
void __iomem*reg_base;
spinlock_t  lock;
 
-- 
1.7.9.5

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


RE: [PATCH 3/5] rc: img-ir: biphase enabled with workaround

2014-12-12 Thread Sifan Naeem


 -Original Message-
 From: James Hogan
 Sent: 12 December 2014 10:56
 To: Sifan Naeem; mche...@osg.samsung.com
 Cc: linux-ker...@vger.kernel.org; linux-media@vger.kernel.org; James
 Hartley; Ezequiel Garcia
 Subject: Re: [PATCH 3/5] rc: img-ir: biphase enabled with workaround
 
 Hi Sifan,
 
 On 11/12/14 18:54, Sifan Naeem wrote:
  +/*
  + * Timer function to re-enable the current protocol after it had
  +been
  + * cleared when invalid interrupts were generated due to a quirk in
  +the
  + * img-ir decoder.
  + */
  +static void img_ir_suspend_timer(unsigned long arg) {
  + struct img_ir_priv *priv = (struct img_ir_priv *)arg;
  +
  + img_ir_write(priv, IMG_IR_IRQ_CLEAR,
  + IMG_IR_IRQ_ALL  ~IMG_IR_IRQ_EDGE);
  +
  + /* Don't set IRQ if it has changed in a different context. */
 
  Should you even be clearing IRQs in that case? Maybe safer to just
  treat that case as a return immediately without touching anything sort
 of situation.
 
  don't have to clear it for this work around to work, so will remove.
 
  + if ((priv-hw.suspend_irqen  IMG_IR_IRQ_EDGE) ==
  + img_ir_read(priv, IMG_IR_IRQ_ENABLE))
  + img_ir_write(priv, IMG_IR_IRQ_ENABLE, priv-
  hw.suspend_irqen);
  + /* enable */
  + img_ir_write(priv, IMG_IR_CONTROL, priv-hw.reg_timings.ctrl); }
 
 To clarify, I was only referring to the case where the irq mask has changed
 unexpectedly. If it hasn't changed then it would seem to make sense to clear
 pending interrupts (i.e. the ones we've been intentionally ignoring) before
 re-enabling them.
 
 When you say it works without, do you mean there never are pending
 interrupts (if you don't press any other buttons on the remote)?
 
Nope, with the change I submitted in v2 (removed the clearing IRQ) there are no 
pending interrupts at the end.
But as before it goes through the workaround couple of times for each interrupt 
before settling down.

Thanks,
Sifan

 Cheers
 James

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


RE: [PATCH 3/5] rc: img-ir: biphase enabled with workaround

2014-12-11 Thread Sifan Naeem


 -Original Message-
 From: James Hogan
 Sent: 08 December 2014 17:18
 To: Sifan Naeem; mche...@osg.samsung.com
 Cc: linux-ker...@vger.kernel.org; linux-media@vger.kernel.org; James
 Hartley; Ezequiel Garcia
 Subject: Re: [PATCH 3/5] rc: img-ir: biphase enabled with workaround
 
 On 04/12/14 15:38, Sifan Naeem wrote:
  Biphase decoding in the current img-ir has got a quirk, where multiple
  Interrupts are generated when an incomplete IR code is received by the
  decoder.
 
  Patch adds a work around for the quirk and enables biphase decoding.
 
  Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
  ---
   drivers/media/rc/img-ir/img-ir-hw.c |   56
 +--
   drivers/media/rc/img-ir/img-ir-hw.h |2 ++
   2 files changed, 55 insertions(+), 3 deletions(-)
 
  diff --git a/drivers/media/rc/img-ir/img-ir-hw.c
  b/drivers/media/rc/img-ir/img-ir-hw.c
  index 4a1407b..a977467 100644
  --- a/drivers/media/rc/img-ir/img-ir-hw.c
  +++ b/drivers/media/rc/img-ir/img-ir-hw.c
  @@ -52,6 +52,11 @@ static struct img_ir_decoder *img_ir_decoders[] = {
 
   #define IMG_IR_QUIRK_CODE_BROKEN   0x1 /* Decode is broken
 */
   #define IMG_IR_QUIRK_CODE_LEN_INCR 0x2 /* Bit length needs
 increment */
  +/*
  + * The decoder generates rapid interrupts without actually having
  + * received any new data after an incomplete IR code is decoded.
  + */
  +#define IMG_IR_QUIRK_CODE_IRQ  0x4
 
   /* functions for preprocessing timings, ensuring max is set */
 
  @@ -547,6 +552,7 @@ static void img_ir_set_decoder(struct img_ir_priv
  *priv,
 
  /* stop the end timer and switch back to normal mode */
  del_timer_sync(hw-end_timer);
  +   del_timer_sync(hw-suspend_timer);
 
 FYI, this'll need rebasing due to conflicting with img-ir/hw: Fix potential
 deadlock stopping timer. The new del_timer_sync will need to be when spin
 lock isn't held, i.e. still next to the other one, and don't forget to ensure 
 that
 suspend_timer doesn't get started if
 hw-stopping.
 
Yes, I'll rebase and resend the patch.

  hw-mode = IMG_IR_M_NORMAL;
 
  /* clear the wakeup scancode filter */ @@ -843,6 +849,26 @@ static
  void img_ir_end_timer(unsigned long arg)
  spin_unlock_irq(priv-lock);
   }
 
  +/*
  + * Timer function to re-enable the current protocol after it had been
  + * cleared when invalid interrupts were generated due to a quirk in
  +the
  + * img-ir decoder.
  + */
  +static void img_ir_suspend_timer(unsigned long arg) {
  +   struct img_ir_priv *priv = (struct img_ir_priv *)arg;
  +
 
 You should take the spin lock for most of this function now that
 img-ir/hw: Fix potential deadlock stopping timer is applied and it is safe 
 to
 do so.
 
done
  +   img_ir_write(priv, IMG_IR_IRQ_CLEAR,
  +   IMG_IR_IRQ_ALL  ~IMG_IR_IRQ_EDGE);
  +
  +   /* Don't set IRQ if it has changed in a different context. */
 
 Wouldn't hurt to clarify this while you're at it (it confused me for a moment
 thinking it was concerned about the enabled raw event IRQs
 (IMG_IR_IRQ_EDGE) changing).
 
Ok
 Maybe Don't overwrite enabled valid/match IRQs if they have already been
 changed by e.g. a filter change.
 
 Should you even be clearing IRQs in that case? Maybe safer to just treat that
 case as a return immediately without touching anything sort of situation.
 
don't have to clear it for this work around to work, so will remove.

  +   if ((priv-hw.suspend_irqen  IMG_IR_IRQ_EDGE) ==
  +   img_ir_read(priv, IMG_IR_IRQ_ENABLE))
  +   img_ir_write(priv, IMG_IR_IRQ_ENABLE, priv-
 hw.suspend_irqen);
  +   /* enable */
  +   img_ir_write(priv, IMG_IR_CONTROL, priv-hw.reg_timings.ctrl); }
  +
   #ifdef CONFIG_COMMON_CLK
   static void img_ir_change_frequency(struct img_ir_priv *priv,
  struct clk_notifier_data *change) @@ -
 908,15 +934,37 @@ void
  img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status)
  if (!hw-decoder)
  return;
 
  +   ct = hw-decoder-control.code_type;
  +
  ir_status = img_ir_read(priv, IMG_IR_STATUS);
  -   if (!(ir_status  (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)))
  +   if (!(ir_status  (IMG_IR_RXDVAL | IMG_IR_RXDVALD2))) {
  +   if (!(priv-hw.ct_quirks[ct]  IMG_IR_QUIRK_CODE_IRQ))
 
 (I suggest adding || hw-stopping to this case)
 
  +   return;
  +   /*
  +* The below functionality is added as a work around to stop
  +* multiple Interrupts generated when an incomplete IR code
 is
  +* received by the decoder.
  +* The decoder generates rapid interrupts without actually
  +* having received any new data. After a single interrupt it's
  +* expected to clear up, but instead multiple interrupts are
  +* rapidly generated. only way to get out of this loop is to
  +* reset the control register after a short delay.
  +*/
  +   img_ir_write(priv

[PATCH v2 5/5] rc: img-ir: add philips rc6 decoder module

2014-12-11 Thread Sifan Naeem
Add img-ir module for decoding Philips rc6 protocol.

Changes from v1:
 * Phillips renamed to Philips

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/Kconfig  |8 +++
 drivers/media/rc/img-ir/Makefile |1 +
 drivers/media/rc/img-ir/img-ir-hw.c  |3 +
 drivers/media/rc/img-ir/img-ir-hw.h  |1 +
 drivers/media/rc/img-ir/img-ir-rc6.c |  117 ++
 5 files changed, 130 insertions(+)
 create mode 100644 drivers/media/rc/img-ir/img-ir-rc6.c

diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig
index b20b3e9..a896d3c 100644
--- a/drivers/media/rc/img-ir/Kconfig
+++ b/drivers/media/rc/img-ir/Kconfig
@@ -67,3 +67,11 @@ config IR_IMG_RC5
help
   Say Y here to enable support for the RC5 protocol in the ImgTec
   infrared decoder block.
+
+config IR_IMG_RC6
+   bool Philips RC6 protocol support
+   depends on IR_IMG_HW
+   help
+  Say Y here to enable support for the RC6 protocol in the ImgTec
+  infrared decoder block.
+  Note: This version only supports mode 0.
diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile
index 898b1b8..8e6d458 100644
--- a/drivers/media/rc/img-ir/Makefile
+++ b/drivers/media/rc/img-ir/Makefile
@@ -7,6 +7,7 @@ img-ir-$(CONFIG_IR_IMG_SONY)+= img-ir-sony.o
 img-ir-$(CONFIG_IR_IMG_SHARP)  += img-ir-sharp.o
 img-ir-$(CONFIG_IR_IMG_SANYO)  += img-ir-sanyo.o
 img-ir-$(CONFIG_IR_IMG_RC5)+= img-ir-rc5.o
+img-ir-$(CONFIG_IR_IMG_RC6)+= img-ir-rc6.o
 img-ir-objs:= $(img-ir-y)
 
 obj-$(CONFIG_IR_IMG)   += img-ir.o
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index 13f0b1e..7bb71bc 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -45,6 +45,9 @@ static struct img_ir_decoder *img_ir_decoders[] = {
 #ifdef CONFIG_IR_IMG_RC5
img_ir_rc5,
 #endif
+#ifdef CONFIG_IR_IMG_RC6
+   img_ir_rc6,
+#endif
NULL
 };
 
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h 
b/drivers/media/rc/img-ir/img-ir-hw.h
index b9e799d5..91a2977 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -188,6 +188,7 @@ extern struct img_ir_decoder img_ir_sony;
 extern struct img_ir_decoder img_ir_sharp;
 extern struct img_ir_decoder img_ir_sanyo;
 extern struct img_ir_decoder img_ir_rc5;
+extern struct img_ir_decoder img_ir_rc6;
 
 /**
  * struct img_ir_reg_timings - Reg values for decoder timings at clock rate.
diff --git a/drivers/media/rc/img-ir/img-ir-rc6.c 
b/drivers/media/rc/img-ir/img-ir-rc6.c
new file mode 100644
index 000..de1e275
--- /dev/null
+++ b/drivers/media/rc/img-ir/img-ir-rc6.c
@@ -0,0 +1,117 @@
+/*
+ * ImgTec IR Decoder setup for Philips RC-6 protocol.
+ *
+ * Copyright 2012-2014 Imagination Technologies Ltd.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include img-ir-hw.h
+
+/* Convert RC6 data to a scancode */
+static int img_ir_rc6_scancode(int len, u64 raw, u64 enabled_protocols,
+   struct img_ir_scancode_req *request)
+{
+   unsigned int addr, cmd, mode, trl1, trl2;
+
+   /*
+* Due to a side effect of the decoder handling the double length
+* Trailer bit, the header information is a bit scrambled, and the
+* raw data is shifted incorrectly.
+* This workaround effectively recovers the header bits.
+*
+* The Header field should look like this:
+*
+* StartBit ModeBit2 ModeBit1 ModeBit0 TrailerBit
+*
+* But what we get is:
+*
+* ModeBit2 ModeBit1 ModeBit0 TrailerBit1 TrailerBit2
+*
+* The start bit is not important to recover the scancode.
+*/
+
+   raw = 27;
+
+   trl1= (raw   17)   0x01;
+   trl2= (raw   16)   0x01;
+
+   mode= (raw   18)   0x07;
+   addr= (raw8)   0xff;
+   cmd =  raw   0xff;
+
+   /*
+* Due to the above explained irregularity the trailer bits cannot
+* have the same value.
+*/
+   if (trl1 == trl2)
+   return -EINVAL;
+
+   /* Only mode 0 supported for now */
+   if (mode)
+   return -EINVAL;
+
+   request-protocol = RC_TYPE_RC6_0;
+   request-scancode = addr  8 | cmd;
+   request-toggle   = trl2;
+   return IMG_IR_SCANCODE;
+}
+
+/* Convert RC6 scancode to RC6 data filter */
+static int img_ir_rc6_filter(const struct rc_scancode_filter *in,
+struct img_ir_filter *out, u64 protocols)
+{
+   /* Not supported by the hw. */
+   return -EINVAL;
+}
+
+/*
+ * RC-6 decoder

[PATCH v2 3/5] rc: img-ir: biphase enabled with workaround

2014-12-11 Thread Sifan Naeem
Biphase decoding in the current img-ir has got a quirk, where multiple
Interrupts are generated when an incomplete IR code is received by the
decoder.

Patch adds a work around for the quirk and enables biphase decoding.

Changes from v1:
 * rebased due to conflict with img-ir/hw: Fix potential deadlock stopping 
timer
 * spinlock taken in img_ir_suspend_timer
 * check for hw-stopping before handling quirks in img_ir_isr_hw
 * new memeber added to img_ir_priv_hw to save irq status over suspend

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/img-ir-hw.c |   60 +--
 drivers/media/rc/img-ir/img-ir-hw.h |4 +++
 2 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index 9cecda7..5c32f05 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -52,6 +52,11 @@ static struct img_ir_decoder *img_ir_decoders[] = {
 
 #define IMG_IR_QUIRK_CODE_BROKEN   0x1 /* Decode is broken */
 #define IMG_IR_QUIRK_CODE_LEN_INCR 0x2 /* Bit length needs increment */
+/*
+ * The decoder generates rapid interrupts without actually having
+ * received any new data after an incomplete IR code is decoded.
+ */
+#define IMG_IR_QUIRK_CODE_IRQ  0x4
 
 /* functions for preprocessing timings, ensuring max is set */
 
@@ -542,6 +547,7 @@ static void img_ir_set_decoder(struct img_ir_priv *priv,
 */
spin_unlock_irq(priv-lock);
del_timer_sync(hw-end_timer);
+   del_timer_sync(hw-suspend_timer);
spin_lock_irq(priv-lock);
 
hw-stopping = false;
@@ -861,6 +867,29 @@ static void img_ir_end_timer(unsigned long arg)
spin_unlock_irq(priv-lock);
 }
 
+/*
+ * Timer function to re-enable the current protocol after it had been
+ * cleared when invalid interrupts were generated due to a quirk in the
+ * img-ir decoder.
+ */
+static void img_ir_suspend_timer(unsigned long arg)
+{
+   struct img_ir_priv *priv = (struct img_ir_priv *)arg;
+
+   spin_lock_irq(priv-lock);
+   /*
+* Don't overwrite enabled valid/match IRQs if they have already been
+* changed by e.g. a filter change.
+*/
+   if ((priv-hw.quirk_suspend_irq  IMG_IR_IRQ_EDGE) ==
+   img_ir_read(priv, IMG_IR_IRQ_ENABLE))
+   img_ir_write(priv, IMG_IR_IRQ_ENABLE,
+   priv-hw.quirk_suspend_irq);
+   /* enable */
+   img_ir_write(priv, IMG_IR_CONTROL, priv-hw.reg_timings.ctrl);
+   spin_unlock_irq(priv-lock);
+}
+
 #ifdef CONFIG_COMMON_CLK
 static void img_ir_change_frequency(struct img_ir_priv *priv,
struct clk_notifier_data *change)
@@ -926,15 +955,38 @@ void img_ir_isr_hw(struct img_ir_priv *priv, u32 
irq_status)
if (!hw-decoder)
return;
 
+   ct = hw-decoder-control.code_type;
+
ir_status = img_ir_read(priv, IMG_IR_STATUS);
-   if (!(ir_status  (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)))
+   if (!(ir_status  (IMG_IR_RXDVAL | IMG_IR_RXDVALD2))) {
+   if (!(priv-hw.ct_quirks[ct]  IMG_IR_QUIRK_CODE_IRQ) ||
+   hw-stopping)
+   return;
+   /*
+* The below functionality is added as a work around to stop
+* multiple Interrupts generated when an incomplete IR code is
+* received by the decoder.
+* The decoder generates rapid interrupts without actually
+* having received any new data. After a single interrupt it's
+* expected to clear up, but instead multiple interrupts are
+* rapidly generated. only way to get out of this loop is to
+* reset the control register after a short delay.
+*/
+   img_ir_write(priv, IMG_IR_CONTROL, 0);
+   hw-quirk_suspend_irq = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
+   img_ir_write(priv, IMG_IR_IRQ_ENABLE,
+hw-quirk_suspend_irq  IMG_IR_IRQ_EDGE);
+
+   /* Timer activated to re-enable the protocol. */
+   mod_timer(hw-suspend_timer,
+ jiffies + msecs_to_jiffies(5));
return;
+   }
ir_status = ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
img_ir_write(priv, IMG_IR_STATUS, ir_status);
 
len = (ir_status  IMG_IR_RXDLEN)  IMG_IR_RXDLEN_SHIFT;
/* some versions report wrong length for certain code types */
-   ct = hw-decoder-control.code_type;
if (hw-ct_quirks[ct]  IMG_IR_QUIRK_CODE_LEN_INCR)
++len;
 
@@ -976,7 +1028,7 @@ static void img_ir_probe_hw_caps(struct img_ir_priv *priv)
hw-ct_quirks[IMG_IR_CODETYPE_PULSELEN]
|= IMG_IR_QUIRK_CODE_LEN_INCR;
hw-ct_quirks[IMG_IR_CODETYPE_BIPHASE

[PATCH v2 4/5] rc: img-ir: add philips rc5 decoder module

2014-12-11 Thread Sifan Naeem
Add img-ir module for decoding Philips rc5 protocol.

Changes from v1:
 * Phillips renamed to Philips

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/Kconfig  |7 +++
 drivers/media/rc/img-ir/Makefile |1 +
 drivers/media/rc/img-ir/img-ir-hw.c  |3 ++
 drivers/media/rc/img-ir/img-ir-hw.h  |1 +
 drivers/media/rc/img-ir/img-ir-rc5.c |   88 ++
 5 files changed, 100 insertions(+)
 create mode 100644 drivers/media/rc/img-ir/img-ir-rc5.c

diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig
index 580715c..b20b3e9 100644
--- a/drivers/media/rc/img-ir/Kconfig
+++ b/drivers/media/rc/img-ir/Kconfig
@@ -60,3 +60,10 @@ config IR_IMG_SANYO
help
   Say Y here to enable support for the Sanyo protocol (used by Sanyo,
   Aiwa, Chinon remotes) in the ImgTec infrared decoder block.
+
+config IR_IMG_RC5
+   bool Philips RC5 protocol support
+   depends on IR_IMG_HW
+   help
+  Say Y here to enable support for the RC5 protocol in the ImgTec
+  infrared decoder block.
diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile
index 92a459d..898b1b8 100644
--- a/drivers/media/rc/img-ir/Makefile
+++ b/drivers/media/rc/img-ir/Makefile
@@ -6,6 +6,7 @@ img-ir-$(CONFIG_IR_IMG_JVC) += img-ir-jvc.o
 img-ir-$(CONFIG_IR_IMG_SONY)   += img-ir-sony.o
 img-ir-$(CONFIG_IR_IMG_SHARP)  += img-ir-sharp.o
 img-ir-$(CONFIG_IR_IMG_SANYO)  += img-ir-sanyo.o
+img-ir-$(CONFIG_IR_IMG_RC5)+= img-ir-rc5.o
 img-ir-objs:= $(img-ir-y)
 
 obj-$(CONFIG_IR_IMG)   += img-ir.o
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index 5c32f05..13f0b1e 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -42,6 +42,9 @@ static struct img_ir_decoder *img_ir_decoders[] = {
 #ifdef CONFIG_IR_IMG_SANYO
img_ir_sanyo,
 #endif
+#ifdef CONFIG_IR_IMG_RC5
+   img_ir_rc5,
+#endif
NULL
 };
 
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h 
b/drivers/media/rc/img-ir/img-ir-hw.h
index b31ffc9..b9e799d5 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -187,6 +187,7 @@ extern struct img_ir_decoder img_ir_jvc;
 extern struct img_ir_decoder img_ir_sony;
 extern struct img_ir_decoder img_ir_sharp;
 extern struct img_ir_decoder img_ir_sanyo;
+extern struct img_ir_decoder img_ir_rc5;
 
 /**
  * struct img_ir_reg_timings - Reg values for decoder timings at clock rate.
diff --git a/drivers/media/rc/img-ir/img-ir-rc5.c 
b/drivers/media/rc/img-ir/img-ir-rc5.c
new file mode 100644
index 000..a8a28a3
--- /dev/null
+++ b/drivers/media/rc/img-ir/img-ir-rc5.c
@@ -0,0 +1,88 @@
+/*
+ * ImgTec IR Decoder setup for Philips RC-5 protocol.
+ *
+ * Copyright 2012-2014 Imagination Technologies Ltd.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include img-ir-hw.h
+
+/* Convert RC5 data to a scancode */
+static int img_ir_rc5_scancode(int len, u64 raw, u64 enabled_protocols,
+   struct img_ir_scancode_req *request)
+{
+   unsigned int addr, cmd, tgl, start;
+
+   /* Quirk in the decoder shifts everything by 2 to the left. */
+   raw   = 2;
+
+   start   =  (raw  13)   0x01;
+   tgl =  (raw  11)   0x01;
+   addr=  (raw   6)   0x1f;
+   cmd =   raw  0x3f;
+   /*
+* 12th bit is used to extend the command in extended RC5 and has
+* no effect on standard RC5.
+*/
+   cmd += ((raw  12)  0x01) ? 0 : 0x40;
+
+   if (!start)
+   return -EINVAL;
+
+   request-protocol = RC_TYPE_RC5;
+   request-scancode = addr  8 | cmd;
+   request-toggle   = tgl;
+   return IMG_IR_SCANCODE;
+}
+
+/* Convert RC5 scancode to RC5 data filter */
+static int img_ir_rc5_filter(const struct rc_scancode_filter *in,
+struct img_ir_filter *out, u64 protocols)
+{
+   /* Not supported by the hw. */
+   return -EINVAL;
+}
+
+/*
+ * RC-5 decoder
+ * see http://www.sbprojects.com/knowledge/ir/rc5.php
+ */
+struct img_ir_decoder img_ir_rc5 = {
+   .type  = RC_BIT_RC5,
+   .control   = {
+   .bitoriend2 = 1,
+   .code_type  = IMG_IR_CODETYPE_BIPHASE,
+   .decodend2  = 1,
+   },
+   /* main timings */
+   .tolerance  = 16,
+   .unit   = 88, /* 1/36k*32=888.888microseconds */
+   .timings= {
+   /* 10 symbol */
+   .s10 = {
+   .pulse  = { 1 },
+   .space  = { 1 },
+   },
+
+   /* 11 symbol

[PATCH v2 1/5] rc: img-ir: add scancode requests to a struct

2014-12-11 Thread Sifan Naeem
The information being requested of hardware decode callbacks through
the img-ir-hw scancode API is mounting up, so combine it into a struct
which can be passed in with a single pointer rather than multiple
pointer arguments. This allows it to be extended more easily without
touching all the hardware decode callbacks.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/img-ir-hw.c|   16 +---
 drivers/media/rc/img-ir/img-ir-hw.h|   16 ++--
 drivers/media/rc/img-ir/img-ir-jvc.c   |8 
 drivers/media/rc/img-ir/img-ir-nec.c   |   24 
 drivers/media/rc/img-ir/img-ir-sanyo.c |8 
 drivers/media/rc/img-ir/img-ir-sharp.c |8 
 drivers/media/rc/img-ir/img-ir-sony.c  |   12 ++--
 7 files changed, 53 insertions(+), 39 deletions(-)

diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index 2fd47c9..88fada5 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -806,20 +806,22 @@ static void img_ir_handle_data(struct img_ir_priv *priv, 
u32 len, u64 raw)
struct img_ir_priv_hw *hw = priv-hw;
const struct img_ir_decoder *dec = hw-decoder;
int ret = IMG_IR_SCANCODE;
-   u32 scancode;
-   enum rc_type protocol = RC_TYPE_UNKNOWN;
+   struct img_ir_scancode_req request;
+
+   request.protocol = RC_TYPE_UNKNOWN;
 
if (dec-scancode)
-   ret = dec-scancode(len, raw, protocol, scancode, 
hw-enabled_protocols);
+   ret = dec-scancode(len, raw, hw-enabled_protocols, request);
else if (len = 32)
-   scancode = (u32)raw;
+   request.scancode = (u32)raw;
else if (len  32)
-   scancode = (u32)raw  ((1  len)-1);
+   request.scancode = (u32)raw  ((1  len)-1);
dev_dbg(priv-dev, data (%u bits) = %#llx\n,
len, (unsigned long long)raw);
if (ret == IMG_IR_SCANCODE) {
-   dev_dbg(priv-dev, decoded scan code %#x\n, scancode);
-   rc_keydown(hw-rdev, protocol, scancode, 0);
+   dev_dbg(priv-dev, decoded scan code %#x\n,
+   request.scancode);
+   rc_keydown(hw-rdev, request.protocol, request.scancode, 0);
img_ir_end_repeat(priv);
} else if (ret == IMG_IR_REPEATCODE) {
if (hw-mode == IMG_IR_M_REPEATING) {
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h 
b/drivers/media/rc/img-ir/img-ir-hw.h
index 5c2b216..aeef3d1 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -133,6 +133,18 @@ struct img_ir_timing_regvals {
 #define IMG_IR_REPEATCODE  1   /* repeat the previous code */
 
 /**
+ * struct img_ir_scancode_req - Scancode request data.
+ * @protocol:  Protocol code of received message (defaults to
+ * RC_TYPE_UNKNOWN).
+ * @scancode:  Scan code of received message (must be written by
+ * handler if IMG_IR_SCANCODE is returned).
+ */
+struct img_ir_scancode_req {
+   enum rc_type protocol;
+   u32 scancode;
+};
+
+/**
  * struct img_ir_decoder - Decoder settings for an IR protocol.
  * @type:  Protocol types bitmap.
  * @tolerance: Timing tolerance as a percentage (default 10%).
@@ -162,8 +174,8 @@ struct img_ir_decoder {
struct img_ir_control   control;
 
/* scancode logic */
-   int (*scancode)(int len, u64 raw, enum rc_type *protocol,
-   u32 *scancode, u64 enabled_protocols);
+   int (*scancode)(int len, u64 raw, u64 enabled_protocols,
+   struct img_ir_scancode_req *request);
int (*filter)(const struct rc_scancode_filter *in,
  struct img_ir_filter *out, u64 protocols);
 };
diff --git a/drivers/media/rc/img-ir/img-ir-jvc.c 
b/drivers/media/rc/img-ir/img-ir-jvc.c
index a60dda8..d3e2fc0 100644
--- a/drivers/media/rc/img-ir/img-ir-jvc.c
+++ b/drivers/media/rc/img-ir/img-ir-jvc.c
@@ -12,8 +12,8 @@
 #include img-ir-hw.h
 
 /* Convert JVC data to a scancode */
-static int img_ir_jvc_scancode(int len, u64 raw, enum rc_type *protocol,
-  u32 *scancode, u64 enabled_protocols)
+static int img_ir_jvc_scancode(int len, u64 raw, u64 enabled_protocols,
+  struct img_ir_scancode_req *request)
 {
unsigned int cust, data;
 
@@ -23,8 +23,8 @@ static int img_ir_jvc_scancode(int len, u64 raw, enum rc_type 
*protocol,
cust = (raw  0)  0xff;
data = (raw  8)  0xff;
 
-   *protocol = RC_TYPE_JVC;
-   *scancode = cust  8 | data;
+   request-protocol = RC_TYPE_JVC;
+   request-scancode = cust  8 | data;
return IMG_IR_SCANCODE;
 }
 
diff --git a/drivers/media/rc/img-ir/img-ir-nec.c 
b/drivers/media/rc/img-ir/img-ir-nec.c
index 7398975..27a7ea8 100644
--- a/drivers/media/rc/img-ir/img-ir-nec.c
+++ b/drivers/media/rc

[PATCH v2 2/5] rc: img-ir: pass toggle bit to the rc driver

2014-12-11 Thread Sifan Naeem
Add toggle bit to struct img_ir_scancode_req so that protocols can
provide it to img_ir_handle_data(), and pass that toggle bit up to
rc_keydown instead of 0.

This is needed for the upcoming rc-5 and rc-6 patches.

Change from v1:
 * Typo Corrected in the commit message.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/img-ir-hw.c |8 +---
 drivers/media/rc/img-ir/img-ir-hw.h |2 ++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index 88fada5..9cecda7 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -809,6 +809,7 @@ static void img_ir_handle_data(struct img_ir_priv *priv, 
u32 len, u64 raw)
struct img_ir_scancode_req request;
 
request.protocol = RC_TYPE_UNKNOWN;
+   request.toggle   = 0;
 
if (dec-scancode)
ret = dec-scancode(len, raw, hw-enabled_protocols, request);
@@ -819,9 +820,10 @@ static void img_ir_handle_data(struct img_ir_priv *priv, 
u32 len, u64 raw)
dev_dbg(priv-dev, data (%u bits) = %#llx\n,
len, (unsigned long long)raw);
if (ret == IMG_IR_SCANCODE) {
-   dev_dbg(priv-dev, decoded scan code %#x\n,
-   request.scancode);
-   rc_keydown(hw-rdev, request.protocol, request.scancode, 0);
+   dev_dbg(priv-dev, decoded scan code %#x, toggle %u\n,
+   request.scancode, request.toggle);
+   rc_keydown(hw-rdev, request.protocol, request.scancode,
+  request.toggle);
img_ir_end_repeat(priv);
} else if (ret == IMG_IR_REPEATCODE) {
if (hw-mode == IMG_IR_M_REPEATING) {
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h 
b/drivers/media/rc/img-ir/img-ir-hw.h
index aeef3d1..beac3a6 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -138,10 +138,12 @@ struct img_ir_timing_regvals {
  * RC_TYPE_UNKNOWN).
  * @scancode:  Scan code of received message (must be written by
  * handler if IMG_IR_SCANCODE is returned).
+ * @toggle:Toggle bit (defaults to 0).
  */
 struct img_ir_scancode_req {
enum rc_type protocol;
u32 scancode;
+   u8 toggle;
 };
 
 /**
-- 
1.7.9.5

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


[PATCH v2 0/5] rc: img-ir: rc5 and rc6 support added

2014-12-11 Thread Sifan Naeem
This patch sets adds support for rc5 and rc6 decoder modules along with
workarounds for quirks in the hw which surfaces when decoding in 
biphase mode required by rc5 and rc6.

Changes from v1:
 * Typo Corrected in the commit message
 * Rebased due to conflict with img-ir/hw: Fix potential deadlock stopping 
timer
 * spinlock taken in img_ir_suspend_timer
 * Check for hw-stopping before handling quirks in img_ir_isr_hw
 * New member added to img_ir_priv_hw to save irq status over suspend
 * Phillips renamed to Philips

Sifan Naeem (5):
  rc: img-ir: add scancode requests to a struct
  rc: img-ir: pass toggle bit to the rc driver
  rc: img-ir: biphase enabled with workaround
  rc: img-ir: add philips rc5 decoder module
  rc: img-ir: add philips rc6 decoder module

 drivers/media/rc/img-ir/Kconfig|   15 
 drivers/media/rc/img-ir/Makefile   |2 +
 drivers/media/rc/img-ir/img-ir-hw.c|   84 ---
 drivers/media/rc/img-ir/img-ir-hw.h|   24 ++-
 drivers/media/rc/img-ir/img-ir-jvc.c   |8 +--
 drivers/media/rc/img-ir/img-ir-nec.c   |   24 +++
 drivers/media/rc/img-ir/img-ir-rc5.c   |   88 
 drivers/media/rc/img-ir/img-ir-rc6.c   |  117 
 drivers/media/rc/img-ir/img-ir-sanyo.c |8 +--
 drivers/media/rc/img-ir/img-ir-sharp.c |8 +--
 drivers/media/rc/img-ir/img-ir-sony.c  |   12 ++--
 11 files changed, 348 insertions(+), 42 deletions(-)
 create mode 100644 drivers/media/rc/img-ir/img-ir-rc5.c
 create mode 100644 drivers/media/rc/img-ir/img-ir-rc6.c

-- 
1.7.9.5

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


[PATCH 5/5] rc: img-ir: add philips rc6 decoder module

2014-12-04 Thread Sifan Naeem
Add img-ir module for decoding Philips rc6 protocol.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/Kconfig  |8 +++
 drivers/media/rc/img-ir/Makefile |1 +
 drivers/media/rc/img-ir/img-ir-hw.c  |3 +
 drivers/media/rc/img-ir/img-ir-hw.h  |1 +
 drivers/media/rc/img-ir/img-ir-rc6.c |  117 ++
 5 files changed, 130 insertions(+)
 create mode 100644 drivers/media/rc/img-ir/img-ir-rc6.c

diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig
index b5b114f..4d3fca9 100644
--- a/drivers/media/rc/img-ir/Kconfig
+++ b/drivers/media/rc/img-ir/Kconfig
@@ -66,3 +66,11 @@ config IR_IMG_RC5
help
   Say Y here to enable support for the RC5 protocol in the ImgTec
   infrared decoder block.
+
+config IR_IMG_RC6
+   bool Phillips RC6 protocol support
+   depends on IR_IMG_HW
+   help
+  Say Y here to enable support for the RC6 protocol in the ImgTec
+  infrared decoder block.
+  Note: This version only supports mode 0.
diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile
index 898b1b8..8e6d458 100644
--- a/drivers/media/rc/img-ir/Makefile
+++ b/drivers/media/rc/img-ir/Makefile
@@ -7,6 +7,7 @@ img-ir-$(CONFIG_IR_IMG_SONY)+= img-ir-sony.o
 img-ir-$(CONFIG_IR_IMG_SHARP)  += img-ir-sharp.o
 img-ir-$(CONFIG_IR_IMG_SANYO)  += img-ir-sanyo.o
 img-ir-$(CONFIG_IR_IMG_RC5)+= img-ir-rc5.o
+img-ir-$(CONFIG_IR_IMG_RC6)+= img-ir-rc6.o
 img-ir-objs:= $(img-ir-y)
 
 obj-$(CONFIG_IR_IMG)   += img-ir.o
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index 322cdf8..3b70dc2 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -45,6 +45,9 @@ static struct img_ir_decoder *img_ir_decoders[] = {
 #ifdef CONFIG_IR_IMG_RC5
img_ir_rc5,
 #endif
+#ifdef CONFIG_IR_IMG_RC6
+   img_ir_rc6,
+#endif
NULL
 };
 
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h 
b/drivers/media/rc/img-ir/img-ir-hw.h
index f124ec5..c7b6e1a 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -188,6 +188,7 @@ extern struct img_ir_decoder img_ir_sony;
 extern struct img_ir_decoder img_ir_sharp;
 extern struct img_ir_decoder img_ir_sanyo;
 extern struct img_ir_decoder img_ir_rc5;
+extern struct img_ir_decoder img_ir_rc6;
 
 /**
  * struct img_ir_reg_timings - Reg values for decoder timings at clock rate.
diff --git a/drivers/media/rc/img-ir/img-ir-rc6.c 
b/drivers/media/rc/img-ir/img-ir-rc6.c
new file mode 100644
index 000..bcd0822
--- /dev/null
+++ b/drivers/media/rc/img-ir/img-ir-rc6.c
@@ -0,0 +1,117 @@
+/*
+ * ImgTec IR Decoder setup for Phillips RC-6 protocol.
+ *
+ * Copyright 2012-2014 Imagination Technologies Ltd.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include img-ir-hw.h
+
+/* Convert RC6 data to a scancode */
+static int img_ir_rc6_scancode(int len, u64 raw, u64 enabled_protocols,
+   struct img_ir_scancode_req *request)
+{
+   unsigned int addr, cmd, mode, trl1, trl2;
+
+   /*
+* Due to a side effect of the decoder handling the double length
+* Trailer bit, the header information is a bit scrambled, and the
+* raw data is shifted incorrectly.
+* This workaround effectively recovers the header bits.
+*
+* The Header field should look like this:
+*
+* StartBit ModeBit2 ModeBit1 ModeBit0 TrailerBit
+*
+* But what we get is:
+*
+* ModeBit2 ModeBit1 ModeBit0 TrailerBit1 TrailerBit2
+*
+* The start bit is not important to recover the scancode.
+*/
+
+   raw = 27;
+
+   trl1= (raw   17)   0x01;
+   trl2= (raw   16)   0x01;
+
+   mode= (raw   18)   0x07;
+   addr= (raw8)   0xff;
+   cmd =  raw   0xff;
+
+   /*
+* Due to the above explained irregularity the trailer bits cannot
+* have the same value.
+*/
+   if (trl1 == trl2)
+   return -EINVAL;
+
+   /* Only mode 0 supported for now */
+   if (mode)
+   return -EINVAL;
+
+   request-protocol = RC_TYPE_RC6_0;
+   request-scancode = addr  8 | cmd;
+   request-toggle   = trl2;
+   return IMG_IR_SCANCODE;
+}
+
+/* Convert RC6 scancode to RC6 data filter */
+static int img_ir_rc6_filter(const struct rc_scancode_filter *in,
+struct img_ir_filter *out, u64 protocols)
+{
+   /* Not supported by the hw. */
+   return -EINVAL;
+}
+
+/*
+ * RC-6 decoder
+ * see http://www.sbprojects.com/knowledge/ir/rc6.php

[PATCH 4/5] rc: img-ir: add philips rc5 decoder module

2014-12-04 Thread Sifan Naeem
Add img-ir module for decoding Philips rc5 protocol.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/Kconfig  |7 +++
 drivers/media/rc/img-ir/Makefile |1 +
 drivers/media/rc/img-ir/img-ir-hw.c  |3 ++
 drivers/media/rc/img-ir/img-ir-hw.h  |1 +
 drivers/media/rc/img-ir/img-ir-rc5.c |   88 ++
 5 files changed, 100 insertions(+)
 create mode 100644 drivers/media/rc/img-ir/img-ir-rc5.c

diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig
index 03ba9fc..b5b114f 100644
--- a/drivers/media/rc/img-ir/Kconfig
+++ b/drivers/media/rc/img-ir/Kconfig
@@ -59,3 +59,10 @@ config IR_IMG_SANYO
help
   Say Y here to enable support for the Sanyo protocol (used by Sanyo,
   Aiwa, Chinon remotes) in the ImgTec infrared decoder block.
+
+config IR_IMG_RC5
+   bool Phillips RC5 protocol support
+   depends on IR_IMG_HW
+   help
+  Say Y here to enable support for the RC5 protocol in the ImgTec
+  infrared decoder block.
diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile
index 92a459d..898b1b8 100644
--- a/drivers/media/rc/img-ir/Makefile
+++ b/drivers/media/rc/img-ir/Makefile
@@ -6,6 +6,7 @@ img-ir-$(CONFIG_IR_IMG_JVC) += img-ir-jvc.o
 img-ir-$(CONFIG_IR_IMG_SONY)   += img-ir-sony.o
 img-ir-$(CONFIG_IR_IMG_SHARP)  += img-ir-sharp.o
 img-ir-$(CONFIG_IR_IMG_SANYO)  += img-ir-sanyo.o
+img-ir-$(CONFIG_IR_IMG_RC5)+= img-ir-rc5.o
 img-ir-objs:= $(img-ir-y)
 
 obj-$(CONFIG_IR_IMG)   += img-ir.o
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index a977467..322cdf8 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -42,6 +42,9 @@ static struct img_ir_decoder *img_ir_decoders[] = {
 #ifdef CONFIG_IR_IMG_SANYO
img_ir_sanyo,
 #endif
+#ifdef CONFIG_IR_IMG_RC5
+   img_ir_rc5,
+#endif
NULL
 };
 
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h 
b/drivers/media/rc/img-ir/img-ir-hw.h
index 8578aa7..f124ec5 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -187,6 +187,7 @@ extern struct img_ir_decoder img_ir_jvc;
 extern struct img_ir_decoder img_ir_sony;
 extern struct img_ir_decoder img_ir_sharp;
 extern struct img_ir_decoder img_ir_sanyo;
+extern struct img_ir_decoder img_ir_rc5;
 
 /**
  * struct img_ir_reg_timings - Reg values for decoder timings at clock rate.
diff --git a/drivers/media/rc/img-ir/img-ir-rc5.c 
b/drivers/media/rc/img-ir/img-ir-rc5.c
new file mode 100644
index 000..e1a0829
--- /dev/null
+++ b/drivers/media/rc/img-ir/img-ir-rc5.c
@@ -0,0 +1,88 @@
+/*
+ * ImgTec IR Decoder setup for Phillips RC-5 protocol.
+ *
+ * Copyright 2012-2014 Imagination Technologies Ltd.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include img-ir-hw.h
+
+/* Convert RC5 data to a scancode */
+static int img_ir_rc5_scancode(int len, u64 raw, u64 enabled_protocols,
+   struct img_ir_scancode_req *request)
+{
+   unsigned int addr, cmd, tgl, start;
+
+   /* Quirk in the decoder shifts everything by 2 to the left. */
+   raw   = 2;
+
+   start   =  (raw  13)   0x01;
+   tgl =  (raw  11)   0x01;
+   addr=  (raw   6)   0x1f;
+   cmd =   raw  0x3f;
+   /*
+* 12th bit is used to extend the command in extended RC5 and has
+* no effect on standard RC5.
+*/
+   cmd += ((raw  12)  0x01) ? 0 : 0x40;
+
+   if (!start)
+   return -EINVAL;
+
+   request-protocol = RC_TYPE_RC5;
+   request-scancode = addr  8 | cmd;
+   request-toggle   = tgl;
+   return IMG_IR_SCANCODE;
+}
+
+/* Convert RC5 scancode to RC5 data filter */
+static int img_ir_rc5_filter(const struct rc_scancode_filter *in,
+struct img_ir_filter *out, u64 protocols)
+{
+   /* Not supported by the hw. */
+   return -EINVAL;
+}
+
+/*
+ * RC-5 decoder
+ * see http://www.sbprojects.com/knowledge/ir/rc5.php
+ */
+struct img_ir_decoder img_ir_rc5 = {
+   .type  = RC_BIT_RC5,
+   .control   = {
+   .bitoriend2 = 1,
+   .code_type  = IMG_IR_CODETYPE_BIPHASE,
+   .decodend2  = 1,
+   },
+   /* main timings */
+   .tolerance  = 16,
+   .unit   = 88, /* 1/36k*32=888.888microseconds */
+   .timings= {
+   /* 10 symbol */
+   .s10 = {
+   .pulse  = { 1 },
+   .space  = { 1 },
+   },
+
+   /* 11 symbol */
+   .s11

[PATCH 1/5] rc: img-ir: add scancode requests to a struct

2014-12-04 Thread Sifan Naeem
The information being requested of hardware decode callbacks through
the img-ir-hw scancode API is mounting up, so combine it into a struct
which can be passed in with a single pointer rather than multiple
pointer arguments. This allows it to be extended more easily without
touching all the hardware decode callbacks.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/img-ir-hw.c|   16 +---
 drivers/media/rc/img-ir/img-ir-hw.h|   16 ++--
 drivers/media/rc/img-ir/img-ir-jvc.c   |8 
 drivers/media/rc/img-ir/img-ir-nec.c   |   24 
 drivers/media/rc/img-ir/img-ir-sanyo.c |8 
 drivers/media/rc/img-ir/img-ir-sharp.c |8 
 drivers/media/rc/img-ir/img-ir-sony.c  |   12 ++--
 7 files changed, 53 insertions(+), 39 deletions(-)

diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index ec49f94..61850a6 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -789,20 +789,22 @@ static void img_ir_handle_data(struct img_ir_priv *priv, 
u32 len, u64 raw)
struct img_ir_priv_hw *hw = priv-hw;
const struct img_ir_decoder *dec = hw-decoder;
int ret = IMG_IR_SCANCODE;
-   u32 scancode;
-   enum rc_type protocol = RC_TYPE_UNKNOWN;
+   struct img_ir_scancode_req request;
+
+   request.protocol = RC_TYPE_UNKNOWN;
 
if (dec-scancode)
-   ret = dec-scancode(len, raw, protocol, scancode, 
hw-enabled_protocols);
+   ret = dec-scancode(len, raw, hw-enabled_protocols, request);
else if (len = 32)
-   scancode = (u32)raw;
+   request.scancode = (u32)raw;
else if (len  32)
-   scancode = (u32)raw  ((1  len)-1);
+   request.scancode = (u32)raw  ((1  len)-1);
dev_dbg(priv-dev, data (%u bits) = %#llx\n,
len, (unsigned long long)raw);
if (ret == IMG_IR_SCANCODE) {
-   dev_dbg(priv-dev, decoded scan code %#x\n, scancode);
-   rc_keydown(hw-rdev, protocol, scancode, 0);
+   dev_dbg(priv-dev, decoded scan code %#x\n,
+   request.scancode);
+   rc_keydown(hw-rdev, request.protocol, request.scancode, 0);
img_ir_end_repeat(priv);
} else if (ret == IMG_IR_REPEATCODE) {
if (hw-mode == IMG_IR_M_REPEATING) {
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h 
b/drivers/media/rc/img-ir/img-ir-hw.h
index 8fcc16c..1fc9583 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -133,6 +133,18 @@ struct img_ir_timing_regvals {
 #define IMG_IR_REPEATCODE  1   /* repeat the previous code */
 
 /**
+ * struct img_ir_scancode_req - Scancode request data.
+ * @protocol:  Protocol code of received message (defaults to
+ * RC_TYPE_UNKNOWN).
+ * @scancode:  Scan code of received message (must be written by
+ * handler if IMG_IR_SCANCODE is returned).
+ */
+struct img_ir_scancode_req {
+   enum rc_type protocol;
+   u32 scancode;
+};
+
+/**
  * struct img_ir_decoder - Decoder settings for an IR protocol.
  * @type:  Protocol types bitmap.
  * @tolerance: Timing tolerance as a percentage (default 10%).
@@ -162,8 +174,8 @@ struct img_ir_decoder {
struct img_ir_control   control;
 
/* scancode logic */
-   int (*scancode)(int len, u64 raw, enum rc_type *protocol,
-   u32 *scancode, u64 enabled_protocols);
+   int (*scancode)(int len, u64 raw, u64 enabled_protocols,
+   struct img_ir_scancode_req *request);
int (*filter)(const struct rc_scancode_filter *in,
  struct img_ir_filter *out, u64 protocols);
 };
diff --git a/drivers/media/rc/img-ir/img-ir-jvc.c 
b/drivers/media/rc/img-ir/img-ir-jvc.c
index a60dda8..d3e2fc0 100644
--- a/drivers/media/rc/img-ir/img-ir-jvc.c
+++ b/drivers/media/rc/img-ir/img-ir-jvc.c
@@ -12,8 +12,8 @@
 #include img-ir-hw.h
 
 /* Convert JVC data to a scancode */
-static int img_ir_jvc_scancode(int len, u64 raw, enum rc_type *protocol,
-  u32 *scancode, u64 enabled_protocols)
+static int img_ir_jvc_scancode(int len, u64 raw, u64 enabled_protocols,
+  struct img_ir_scancode_req *request)
 {
unsigned int cust, data;
 
@@ -23,8 +23,8 @@ static int img_ir_jvc_scancode(int len, u64 raw, enum rc_type 
*protocol,
cust = (raw  0)  0xff;
data = (raw  8)  0xff;
 
-   *protocol = RC_TYPE_JVC;
-   *scancode = cust  8 | data;
+   request-protocol = RC_TYPE_JVC;
+   request-scancode = cust  8 | data;
return IMG_IR_SCANCODE;
 }
 
diff --git a/drivers/media/rc/img-ir/img-ir-nec.c 
b/drivers/media/rc/img-ir/img-ir-nec.c
index 7398975..27a7ea8 100644
--- a/drivers/media/rc/img-ir/img-ir-nec.c
+++ b/drivers/media/rc

[PATCH 3/5] rc: img-ir: biphase enabled with workaround

2014-12-04 Thread Sifan Naeem
Biphase decoding in the current img-ir has got a quirk, where multiple
Interrupts are generated when an incomplete IR code is received by the
decoder.

Patch adds a work around for the quirk and enables biphase decoding.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/img-ir-hw.c |   56 +--
 drivers/media/rc/img-ir/img-ir-hw.h |2 ++
 2 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index 4a1407b..a977467 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -52,6 +52,11 @@ static struct img_ir_decoder *img_ir_decoders[] = {
 
 #define IMG_IR_QUIRK_CODE_BROKEN   0x1 /* Decode is broken */
 #define IMG_IR_QUIRK_CODE_LEN_INCR 0x2 /* Bit length needs increment */
+/*
+ * The decoder generates rapid interrupts without actually having
+ * received any new data after an incomplete IR code is decoded.
+ */
+#define IMG_IR_QUIRK_CODE_IRQ  0x4
 
 /* functions for preprocessing timings, ensuring max is set */
 
@@ -547,6 +552,7 @@ static void img_ir_set_decoder(struct img_ir_priv *priv,
 
/* stop the end timer and switch back to normal mode */
del_timer_sync(hw-end_timer);
+   del_timer_sync(hw-suspend_timer);
hw-mode = IMG_IR_M_NORMAL;
 
/* clear the wakeup scancode filter */
@@ -843,6 +849,26 @@ static void img_ir_end_timer(unsigned long arg)
spin_unlock_irq(priv-lock);
 }
 
+/*
+ * Timer function to re-enable the current protocol after it had been
+ * cleared when invalid interrupts were generated due to a quirk in the
+ * img-ir decoder.
+ */
+static void img_ir_suspend_timer(unsigned long arg)
+{
+   struct img_ir_priv *priv = (struct img_ir_priv *)arg;
+
+   img_ir_write(priv, IMG_IR_IRQ_CLEAR,
+   IMG_IR_IRQ_ALL  ~IMG_IR_IRQ_EDGE);
+
+   /* Don't set IRQ if it has changed in a different context. */
+   if ((priv-hw.suspend_irqen  IMG_IR_IRQ_EDGE) ==
+   img_ir_read(priv, IMG_IR_IRQ_ENABLE))
+   img_ir_write(priv, IMG_IR_IRQ_ENABLE, priv-hw.suspend_irqen);
+   /* enable */
+   img_ir_write(priv, IMG_IR_CONTROL, priv-hw.reg_timings.ctrl);
+}
+
 #ifdef CONFIG_COMMON_CLK
 static void img_ir_change_frequency(struct img_ir_priv *priv,
struct clk_notifier_data *change)
@@ -908,15 +934,37 @@ void img_ir_isr_hw(struct img_ir_priv *priv, u32 
irq_status)
if (!hw-decoder)
return;
 
+   ct = hw-decoder-control.code_type;
+
ir_status = img_ir_read(priv, IMG_IR_STATUS);
-   if (!(ir_status  (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)))
+   if (!(ir_status  (IMG_IR_RXDVAL | IMG_IR_RXDVALD2))) {
+   if (!(priv-hw.ct_quirks[ct]  IMG_IR_QUIRK_CODE_IRQ))
+   return;
+   /*
+* The below functionality is added as a work around to stop
+* multiple Interrupts generated when an incomplete IR code is
+* received by the decoder.
+* The decoder generates rapid interrupts without actually
+* having received any new data. After a single interrupt it's
+* expected to clear up, but instead multiple interrupts are
+* rapidly generated. only way to get out of this loop is to
+* reset the control register after a short delay.
+*/
+   img_ir_write(priv, IMG_IR_CONTROL, 0);
+   hw-suspend_irqen = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
+   img_ir_write(priv, IMG_IR_IRQ_ENABLE,
+hw-suspend_irqen  IMG_IR_IRQ_EDGE);
+
+   /* Timer activated to re-enable the protocol. */
+   mod_timer(hw-suspend_timer,
+ jiffies + msecs_to_jiffies(5));
return;
+   }
ir_status = ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
img_ir_write(priv, IMG_IR_STATUS, ir_status);
 
len = (ir_status  IMG_IR_RXDLEN)  IMG_IR_RXDLEN_SHIFT;
/* some versions report wrong length for certain code types */
-   ct = hw-decoder-control.code_type;
if (hw-ct_quirks[ct]  IMG_IR_QUIRK_CODE_LEN_INCR)
++len;
 
@@ -958,7 +1006,7 @@ static void img_ir_probe_hw_caps(struct img_ir_priv *priv)
hw-ct_quirks[IMG_IR_CODETYPE_PULSELEN]
|= IMG_IR_QUIRK_CODE_LEN_INCR;
hw-ct_quirks[IMG_IR_CODETYPE_BIPHASE]
-   |= IMG_IR_QUIRK_CODE_BROKEN;
+   |= IMG_IR_QUIRK_CODE_IRQ;
hw-ct_quirks[IMG_IR_CODETYPE_2BITPULSEPOS]
|= IMG_IR_QUIRK_CODE_BROKEN;
 }
@@ -977,6 +1025,8 @@ int img_ir_probe_hw(struct img_ir_priv *priv)
 
/* Set up the end timer */
setup_timer(hw-end_timer, img_ir_end_timer, (unsigned long)priv);
+   setup_timer(hw-suspend_timer

[PATCH 2/5] rc: img-ir: pass toggle bit to the rc driver

2014-12-04 Thread Sifan Naeem
Add toggle bit to struct img_ir_scancode_req so that protocols can
provide it to img_ir_handle_data(), and pass that toggle bit up to
rc_keydown instead of 0.

This is nedded for the upcoming rc-5 and rc-6 patches.

Signed-off-by: Sifan Naeem sifan.na...@imgtec.com
---
 drivers/media/rc/img-ir/img-ir-hw.c |8 +---
 drivers/media/rc/img-ir/img-ir-hw.h |2 ++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/media/rc/img-ir/img-ir-hw.c 
b/drivers/media/rc/img-ir/img-ir-hw.c
index 61850a6..4a1407b 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -792,6 +792,7 @@ static void img_ir_handle_data(struct img_ir_priv *priv, 
u32 len, u64 raw)
struct img_ir_scancode_req request;
 
request.protocol = RC_TYPE_UNKNOWN;
+   request.toggle   = 0;
 
if (dec-scancode)
ret = dec-scancode(len, raw, hw-enabled_protocols, request);
@@ -802,9 +803,10 @@ static void img_ir_handle_data(struct img_ir_priv *priv, 
u32 len, u64 raw)
dev_dbg(priv-dev, data (%u bits) = %#llx\n,
len, (unsigned long long)raw);
if (ret == IMG_IR_SCANCODE) {
-   dev_dbg(priv-dev, decoded scan code %#x\n,
-   request.scancode);
-   rc_keydown(hw-rdev, request.protocol, request.scancode, 0);
+   dev_dbg(priv-dev, decoded scan code %#x, toggle %u\n,
+   request.scancode, request.toggle);
+   rc_keydown(hw-rdev, request.protocol, request.scancode,
+  request.toggle);
img_ir_end_repeat(priv);
} else if (ret == IMG_IR_REPEATCODE) {
if (hw-mode == IMG_IR_M_REPEATING) {
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h 
b/drivers/media/rc/img-ir/img-ir-hw.h
index 1fc9583..5e59e8e 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -138,10 +138,12 @@ struct img_ir_timing_regvals {
  * RC_TYPE_UNKNOWN).
  * @scancode:  Scan code of received message (must be written by
  * handler if IMG_IR_SCANCODE is returned).
+ * @toggle:Toggle bit (defaults to 0).
  */
 struct img_ir_scancode_req {
enum rc_type protocol;
u32 scancode;
+   u8 toggle;
 };
 
 /**
-- 
1.7.9.5

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


[PATCH 0/5] rc: img-ir: rc5 and rc6 support added

2014-12-04 Thread Sifan Naeem
This patch sets adds support for rc5 and rc6 decoder modules along with
workarounds for quirks in the hw which surfaces when decoding in 
biphase mode required by rc5 and rc6.

This patch set was based on head of linux-next commit:

commit 1ca7c606de868d172afb4eb65e04e290dbdb51ff
Author: Stephen Rothwell s...@canb.auug.org.au
Date:   Thu Dec 4 19:49:10 2014 +1100


Sifan Naeem (5):
  rc: img-ir: add scancode requests to a struct
  rc: img-ir: pass toggle bit to the rc driver
  rc: img-ir: biphase enabled with workaround
  rc: img-ir: add philips rc5 decoder module
  rc: img-ir: add philips rc6 decoder module

 drivers/media/rc/img-ir/Kconfig|   15 
 drivers/media/rc/img-ir/Makefile   |2 +
 drivers/media/rc/img-ir/img-ir-hw.c|   80 +++---
 drivers/media/rc/img-ir/img-ir-hw.h|   22 +-
 drivers/media/rc/img-ir/img-ir-jvc.c   |8 +--
 drivers/media/rc/img-ir/img-ir-nec.c   |   24 +++
 drivers/media/rc/img-ir/img-ir-rc5.c   |   88 
 drivers/media/rc/img-ir/img-ir-rc6.c   |  117 
 drivers/media/rc/img-ir/img-ir-sanyo.c |8 +--
 drivers/media/rc/img-ir/img-ir-sharp.c |8 +--
 drivers/media/rc/img-ir/img-ir-sony.c  |   12 ++--
 11 files changed, 342 insertions(+), 42 deletions(-)
 create mode 100644 drivers/media/rc/img-ir/img-ir-rc5.c
 create mode 100644 drivers/media/rc/img-ir/img-ir-rc6.c

-- 
1.7.9.5

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