public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: James Hogan <james.hogan@imgtec.com>
To: Sifan Naeem <sifan.naeem@imgtec.com>, <mchehab@osg.samsung.com>
Cc: <linux-kernel@vger.kernel.org>, <linux-media@vger.kernel.org>,
	<james.hartley@imgtec.com>, <ezequiel.garcia@imgtec.com>
Subject: Re: [PATCH v2 3/5] rc: img-ir: biphase enabled with workaround
Date: Fri, 12 Dec 2014 12:07:30 +0000	[thread overview]
Message-ID: <548ADA82.80603@imgtec.com> (raw)
In-Reply-To: <1418328386-9802-4-git-send-email-sifan.naeem@imgtec.com>

[-- Attachment #1: Type: text/plain, Size: 7474 bytes --]

Hi Sifan,

On 11/12/14 20:06, 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.
> 
> 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

For future reference, the list of changes between patchset versions is
usually put after a "---" so that it doesn't get included in the final
git commit message. You can also add any Acked-by/Reviewed-by tags
you've been given to new versions of patchset, assuming nothing
significant has changed in that patch (maintainers generally add
relevant tags for you, that are sent in response to the patches being
applied).

Anyway, the whole patchset looks okay to me, aside from the one question
I just asked on patch 3 of v1, which I'm not so sure about. I'll let you
decide whether that needs changing since you have the hardware to verify it.

So for the whole patchset feel free to add my:
Acked-by: James Hogan <james.hogan@imgtec.com>

Thanks
James

> 
> Signed-off-by: Sifan Naeem <sifan.naeem@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]
> -		|= IMG_IR_QUIRK_CODE_BROKEN;
> +		|= IMG_IR_QUIRK_CODE_IRQ;
>  	hw->ct_quirks[IMG_IR_CODETYPE_2BITPULSEPOS]
>  		|= IMG_IR_QUIRK_CODE_BROKEN;
>  }
> @@ -995,6 +1047,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, img_ir_suspend_timer,
> +				(unsigned long)priv);
>  
>  	/* Register a clock notifier */
>  	if (!IS_ERR(priv->clk)) {
> diff --git a/drivers/media/rc/img-ir/img-ir-hw.h b/drivers/media/rc/img-ir/img-ir-hw.h
> index beac3a6..b31ffc9 100644
> --- a/drivers/media/rc/img-ir/img-ir-hw.h
> +++ b/drivers/media/rc/img-ir/img-ir-hw.h
> @@ -218,6 +218,7 @@ enum img_ir_mode {
>   * @rdev:		Remote control device
>   * @clk_nb:		Notifier block for clock notify events.
>   * @end_timer:		Timer until repeat timeout.
> + * @suspend_timer:	Timer to re-enable protocol.
>   * @decoder:		Current decoder settings.
>   * @enabled_protocols:	Currently enabled protocols.
>   * @clk_hz:		Current core clock rate in Hz.
> @@ -228,12 +229,14 @@ enum img_ir_mode {
>   * @stopping:		Indicates that decoder is being taken down and timers
>   *			should not be restarted.
>   * @suspend_irqen:	Saved IRQ enable mask over suspend.
> + * @quirk_suspend_irq:	Saved IRQ enable mask over quirk suspend timer.
>   */
>  struct img_ir_priv_hw {
>  	unsigned int			ct_quirks[4];
>  	struct rc_dev			*rdev;
>  	struct notifier_block		clk_nb;
>  	struct timer_list		end_timer;
> +	struct timer_list		suspend_timer;
>  	const struct img_ir_decoder	*decoder;
>  	u64				enabled_protocols;
>  	unsigned long			clk_hz;
> @@ -244,6 +247,7 @@ struct img_ir_priv_hw {
>  	enum img_ir_mode		mode;
>  	bool				stopping;
>  	u32				suspend_irqen;
> +	u32				quirk_suspend_irq;
>  };
>  
>  static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw)
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

  reply	other threads:[~2014-12-12 12:07 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-11 20:06 [PATCH v2 0/5] rc: img-ir: rc5 and rc6 support added Sifan Naeem
2014-12-11 20:06 ` [PATCH v2 1/5] rc: img-ir: add scancode requests to a struct Sifan Naeem
2014-12-11 20:06 ` [PATCH v2 2/5] rc: img-ir: pass toggle bit to the rc driver Sifan Naeem
2014-12-11 20:06 ` [PATCH v2 3/5] rc: img-ir: biphase enabled with workaround Sifan Naeem
2014-12-12 12:07   ` James Hogan [this message]
2014-12-12 13:55     ` James Hogan
2014-12-11 20:06 ` [PATCH v2 4/5] rc: img-ir: add philips rc5 decoder module Sifan Naeem
2014-12-11 20:06 ` [PATCH v2 5/5] rc: img-ir: add philips rc6 " Sifan Naeem

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=548ADA82.80603@imgtec.com \
    --to=james.hogan@imgtec.com \
    --cc=ezequiel.garcia@imgtec.com \
    --cc=james.hartley@imgtec.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@osg.samsung.com \
    --cc=sifan.naeem@imgtec.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox