RE: [PATCH] rc: img-ir: Add and enable sys clock for IR
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
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()
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
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
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
-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
-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
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
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
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
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
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
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
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
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
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
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
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
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