All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lee Jones <lee.jones@linaro.org>
To: Kiran Gunda <kgunda@codeaurora.org>
Cc: bjorn.andersson@linaro.org, jingoohan1@gmail.com,
	b.zolnierkie@samsung.com, dri-devel@lists.freedesktop.org,
	daniel.thompson@linaro.org, jacek.anaszewski@gmail.com,
	pavel@ucw.cz, robh+dt@kernel.org, mark.rutland@arm.com,
	linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, Andy Gross <agross@kernel.org>,
	linux-arm-msm@vger.kernel.org, linux-fbdev@vger.kernel.org
Subject: Re: [PATCH V7 6/6] backlight: qcom-wled: Add auto string detection logic
Date: Thu, 17 Oct 2019 13:26:53 +0100	[thread overview]
Message-ID: <20191017122653.GO4365@dell> (raw)
In-Reply-To: <1571220826-7740-7-git-send-email-kgunda@codeaurora.org>

On Wed, 16 Oct 2019, Kiran Gunda wrote:

> The auto string detection algorithm checks if the current WLED
> sink configuration is valid. It tries enabling every sink and
> checks if the OVP fault is observed. Based on this information
> it detects and enables the valid sink configuration.
> Auto calibration will be triggered when the OVP fault interrupts
> are seen frequently thereby it tries to fix the sink configuration.
> 
> The auto-detection also kicks in when the connected LED string
> of the display-backlight malfunctions (because of damage) and
> requires the damaged string to be turned off to prevent the
> complete panel and/or board from being damaged.
> 
> Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
> ---
>  drivers/video/backlight/qcom-wled.c | 410 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 404 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c
> index b5b125c..ff7c409 100644
> --- a/drivers/video/backlight/qcom-wled.c
> +++ b/drivers/video/backlight/qcom-wled.c


[...]

> +	/* iterate through the strings one by one */

Please use proper English in comments (less a full stop).

In this case, just s/iterate/Iterate/.

> +	for (i = 0; i < wled->cfg.num_strings; i++) {
> +		sink_test = BIT((WLED4_SINK_REG_CURR_SINK_SHFT + i));
> +
> +		/* Enable feedback control */
> +		rc = regmap_write(wled->regmap, wled->ctrl_addr +
> +				  WLED3_CTRL_REG_FEEDBACK_CONTROL, i + 1);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Failed to enable feedback for SINK %d rc = %d\n",
> +				i + 1, rc);
> +			goto failed_detect;
> +		}
> +
> +		/* enable the sink */

Here too.  And everywhere else.

> +		rc = regmap_write(wled->regmap, wled->sink_addr +
> +				  WLED4_SINK_REG_CURR_SINK, sink_test);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Failed to configure SINK %d rc=%d\n",
> +				i + 1, rc);
> +			goto failed_detect;
> +		}
> +
> +		/* Enable the module */
> +		rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
> +					WLED3_CTRL_REG_MOD_EN,
> +					WLED3_CTRL_REG_MOD_EN_MASK,
> +					WLED3_CTRL_REG_MOD_EN_MASK);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Failed to enable WLED module rc=%d\n",
> +				rc);
> +			goto failed_detect;
> +		}
> +
> +		usleep_range(WLED_SOFT_START_DLY_US,
> +			     WLED_SOFT_START_DLY_US + 1000);
> +
> +		rc = regmap_read(wled->regmap, wled->ctrl_addr +
> +				 WLED3_CTRL_REG_INT_RT_STS, &int_sts);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Error in reading WLED3_CTRL_INT_RT_STS rc=%d\n",
> +				rc);
> +			goto failed_detect;
> +		}
> +
> +		if (int_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS)
> +			dev_dbg(wled->dev, "WLED OVP fault detected with SINK %d\n",
> +				i + 1);

I haven't reviewed the whole patch, but this caught my eye.

I think this should be upgraded to dev_warn().

> +		else
> +			sink_valid |= sink_test;
> +
> +		/* Disable the module */
> +		rc = regmap_update_bits(wled->regmap,
> +					wled->ctrl_addr + WLED3_CTRL_REG_MOD_EN,
> +					WLED3_CTRL_REG_MOD_EN_MASK, 0);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Failed to disable WLED module rc=%d\n",
> +				rc);
> +			goto failed_detect;
> +		}
> +	}
> +
> +	if (!sink_valid) {
> +		dev_err(wled->dev, "No valid WLED sinks found\n");
> +		wled->disabled_by_short = true;
> +		goto failed_detect;
> +	}
> +
> +	if (sink_valid == sink_config) {
> +		dev_dbg(wled->dev, "WLED auto-detection complete, sink-config=%x OK!\n",
> +			sink_config);

Does this really need to be placed in the kernel log?

> +	} else {
> +		dev_warn(wled->dev, "New WLED string configuration found %x\n",
> +			 sink_valid);

Why would the user care about this?  Is it not normal?

> +		sink_config = sink_valid;
> +	}

[...]

> +static irqreturn_t wled_ovp_irq_handler(int irq, void *_wled)
> +{
> +	struct wled *wled = _wled;
> +	int rc;
> +	u32 int_sts, fault_sts;
> +
> +	rc = regmap_read(wled->regmap,
> +			 wled->ctrl_addr + WLED3_CTRL_REG_INT_RT_STS, &int_sts);
> +	if (rc < 0) {
> +		dev_err(wled->dev, "Error in reading WLED3_INT_RT_STS rc=%d\n",
> +			rc);
> +		return IRQ_HANDLED;
> +	}
> +
> +	rc = regmap_read(wled->regmap, wled->ctrl_addr +
> +			 WLED3_CTRL_REG_FAULT_STATUS, &fault_sts);
> +	if (rc < 0) {
> +		dev_err(wled->dev, "Error in reading WLED_FAULT_STATUS rc=%d\n",
> +			rc);
> +		return IRQ_HANDLED;
> +	}
> +
> +	if (fault_sts &
> +		(WLED3_CTRL_REG_OVP_FAULT_BIT | WLED3_CTRL_REG_ILIM_FAULT_BIT))

Break the line at the '|'.

> +		dev_dbg(wled->dev, "WLED OVP fault detected, int_sts=%x fault_sts= %x\n",
> +			int_sts, fault_sts);

dev_warn().

> +	if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT) {
> +		mutex_lock(&wled->lock);
> +		disable_irq_nosync(wled->ovp_irq);
> +
> +		if (wled_auto_detection_required(wled))
> +			wled_auto_string_detection(wled);
> +
> +		enable_irq(wled->ovp_irq);
> +
> +		mutex_unlock(&wled->lock);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static int wled3_setup(struct wled *wled)
>  {
>  	u16 addr;
> @@ -435,8 +775,10 @@ static int wled4_setup(struct wled *wled)
>  		sink_en |= 1 << temp;
>  	}
>  
> -	if (sink_cfg == sink_en)
> -		return 0;
> +	if (sink_cfg == sink_en) {
> +		rc = wled_auto_detection_at_init(wled);
> +		return rc;
> +	}
>  
>  	rc = regmap_update_bits(wled->regmap,
>  				wled->sink_addr + WLED4_SINK_REG_CURR_SINK,
> @@ -499,7 +841,9 @@ static int wled4_setup(struct wled *wled)
>  		return rc;
>  	}
>  
> -	return 0;
> +	rc = wled_auto_detection_at_init(wled);
> +
> +	return rc;
>  }
>  
>  static const struct wled_config wled4_config_defaults = {
> @@ -510,6 +854,7 @@ static int wled4_setup(struct wled *wled)
>  	.switch_freq = 11,
>  	.cabc = false,
>  	.external_pfet = false,
> +	.auto_detection_enabled = false,
>  };
>  
>  static const u32 wled3_boost_i_limit_values[] = {
> @@ -676,6 +1021,7 @@ static int wled_configure(struct wled *wled, int version)
>  		{ "qcom,ext-gen", &cfg->ext_gen, },
>  		{ "qcom,cabc", &cfg->cabc, },
>  		{ "qcom,external-pfet", &cfg->external_pfet, },
> +		{ "qcom,auto-string-detection", &cfg->auto_detection_enabled, },
>  	};
>  
>  	prop_addr = of_get_address(dev->of_node, 0, NULL, NULL);
> @@ -796,6 +1142,40 @@ static int wled_configure_short_irq(struct wled *wled,
>  	return rc;
>  }
>  
> +static int wled_configure_ovp_irq(struct wled *wled,
> +				  struct platform_device *pdev)
> +{
> +	int rc;
> +	u32 val;
> +
> +	wled->ovp_irq = platform_get_irq_byname(pdev, "ovp");
> +	if (wled->ovp_irq < 0) {
> +		dev_dbg(&pdev->dev, "ovp irq is not used\n");

I assume this is optional.  What happens if no IRQ is provided?

If, for instance, polling mode is enabled, maybe something like this
would be better?

      dev_warn(&pdev->dev, "No IRQ found, falling back to polling mode\n");

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

WARNING: multiple messages have this Message-ID (diff)
From: Lee Jones <lee.jones@linaro.org>
To: Kiran Gunda <kgunda@codeaurora.org>
Cc: bjorn.andersson@linaro.org, jingoohan1@gmail.com,
	b.zolnierkie@samsung.com, dri-devel@lists.freedesktop.org,
	daniel.thompson@linaro.org, jacek.anaszewski@gmail.com,
	pavel@ucw.cz, robh+dt@kernel.org, mark.rutland@arm.com,
	linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, Andy Gross <agross@kernel.org>,
	linux-arm-msm@vger.kernel.org, linux-fbdev@vger.kernel.org
Subject: Re: [PATCH V7 6/6] backlight: qcom-wled: Add auto string detection logic
Date: Thu, 17 Oct 2019 12:26:53 +0000	[thread overview]
Message-ID: <20191017122653.GO4365@dell> (raw)
In-Reply-To: <1571220826-7740-7-git-send-email-kgunda@codeaurora.org>

On Wed, 16 Oct 2019, Kiran Gunda wrote:

> The auto string detection algorithm checks if the current WLED
> sink configuration is valid. It tries enabling every sink and
> checks if the OVP fault is observed. Based on this information
> it detects and enables the valid sink configuration.
> Auto calibration will be triggered when the OVP fault interrupts
> are seen frequently thereby it tries to fix the sink configuration.
> 
> The auto-detection also kicks in when the connected LED string
> of the display-backlight malfunctions (because of damage) and
> requires the damaged string to be turned off to prevent the
> complete panel and/or board from being damaged.
> 
> Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
> ---
>  drivers/video/backlight/qcom-wled.c | 410 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 404 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c
> index b5b125c..ff7c409 100644
> --- a/drivers/video/backlight/qcom-wled.c
> +++ b/drivers/video/backlight/qcom-wled.c


[...]

> +	/* iterate through the strings one by one */

Please use proper English in comments (less a full stop).

In this case, just s/iterate/Iterate/.

> +	for (i = 0; i < wled->cfg.num_strings; i++) {
> +		sink_test = BIT((WLED4_SINK_REG_CURR_SINK_SHFT + i));
> +
> +		/* Enable feedback control */
> +		rc = regmap_write(wled->regmap, wled->ctrl_addr +
> +				  WLED3_CTRL_REG_FEEDBACK_CONTROL, i + 1);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Failed to enable feedback for SINK %d rc = %d\n",
> +				i + 1, rc);
> +			goto failed_detect;
> +		}
> +
> +		/* enable the sink */

Here too.  And everywhere else.

> +		rc = regmap_write(wled->regmap, wled->sink_addr +
> +				  WLED4_SINK_REG_CURR_SINK, sink_test);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Failed to configure SINK %d rc=%d\n",
> +				i + 1, rc);
> +			goto failed_detect;
> +		}
> +
> +		/* Enable the module */
> +		rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
> +					WLED3_CTRL_REG_MOD_EN,
> +					WLED3_CTRL_REG_MOD_EN_MASK,
> +					WLED3_CTRL_REG_MOD_EN_MASK);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Failed to enable WLED module rc=%d\n",
> +				rc);
> +			goto failed_detect;
> +		}
> +
> +		usleep_range(WLED_SOFT_START_DLY_US,
> +			     WLED_SOFT_START_DLY_US + 1000);
> +
> +		rc = regmap_read(wled->regmap, wled->ctrl_addr +
> +				 WLED3_CTRL_REG_INT_RT_STS, &int_sts);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Error in reading WLED3_CTRL_INT_RT_STS rc=%d\n",
> +				rc);
> +			goto failed_detect;
> +		}
> +
> +		if (int_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS)
> +			dev_dbg(wled->dev, "WLED OVP fault detected with SINK %d\n",
> +				i + 1);

I haven't reviewed the whole patch, but this caught my eye.

I think this should be upgraded to dev_warn().

> +		else
> +			sink_valid |= sink_test;
> +
> +		/* Disable the module */
> +		rc = regmap_update_bits(wled->regmap,
> +					wled->ctrl_addr + WLED3_CTRL_REG_MOD_EN,
> +					WLED3_CTRL_REG_MOD_EN_MASK, 0);
> +		if (rc < 0) {
> +			dev_err(wled->dev, "Failed to disable WLED module rc=%d\n",
> +				rc);
> +			goto failed_detect;
> +		}
> +	}
> +
> +	if (!sink_valid) {
> +		dev_err(wled->dev, "No valid WLED sinks found\n");
> +		wled->disabled_by_short = true;
> +		goto failed_detect;
> +	}
> +
> +	if (sink_valid = sink_config) {
> +		dev_dbg(wled->dev, "WLED auto-detection complete, sink-config=%x OK!\n",
> +			sink_config);

Does this really need to be placed in the kernel log?

> +	} else {
> +		dev_warn(wled->dev, "New WLED string configuration found %x\n",
> +			 sink_valid);

Why would the user care about this?  Is it not normal?

> +		sink_config = sink_valid;
> +	}

[...]

> +static irqreturn_t wled_ovp_irq_handler(int irq, void *_wled)
> +{
> +	struct wled *wled = _wled;
> +	int rc;
> +	u32 int_sts, fault_sts;
> +
> +	rc = regmap_read(wled->regmap,
> +			 wled->ctrl_addr + WLED3_CTRL_REG_INT_RT_STS, &int_sts);
> +	if (rc < 0) {
> +		dev_err(wled->dev, "Error in reading WLED3_INT_RT_STS rc=%d\n",
> +			rc);
> +		return IRQ_HANDLED;
> +	}
> +
> +	rc = regmap_read(wled->regmap, wled->ctrl_addr +
> +			 WLED3_CTRL_REG_FAULT_STATUS, &fault_sts);
> +	if (rc < 0) {
> +		dev_err(wled->dev, "Error in reading WLED_FAULT_STATUS rc=%d\n",
> +			rc);
> +		return IRQ_HANDLED;
> +	}
> +
> +	if (fault_sts &
> +		(WLED3_CTRL_REG_OVP_FAULT_BIT | WLED3_CTRL_REG_ILIM_FAULT_BIT))

Break the line at the '|'.

> +		dev_dbg(wled->dev, "WLED OVP fault detected, int_sts=%x fault_sts= %x\n",
> +			int_sts, fault_sts);

dev_warn().

> +	if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT) {
> +		mutex_lock(&wled->lock);
> +		disable_irq_nosync(wled->ovp_irq);
> +
> +		if (wled_auto_detection_required(wled))
> +			wled_auto_string_detection(wled);
> +
> +		enable_irq(wled->ovp_irq);
> +
> +		mutex_unlock(&wled->lock);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static int wled3_setup(struct wled *wled)
>  {
>  	u16 addr;
> @@ -435,8 +775,10 @@ static int wled4_setup(struct wled *wled)
>  		sink_en |= 1 << temp;
>  	}
>  
> -	if (sink_cfg = sink_en)
> -		return 0;
> +	if (sink_cfg = sink_en) {
> +		rc = wled_auto_detection_at_init(wled);
> +		return rc;
> +	}
>  
>  	rc = regmap_update_bits(wled->regmap,
>  				wled->sink_addr + WLED4_SINK_REG_CURR_SINK,
> @@ -499,7 +841,9 @@ static int wled4_setup(struct wled *wled)
>  		return rc;
>  	}
>  
> -	return 0;
> +	rc = wled_auto_detection_at_init(wled);
> +
> +	return rc;
>  }
>  
>  static const struct wled_config wled4_config_defaults = {
> @@ -510,6 +854,7 @@ static int wled4_setup(struct wled *wled)
>  	.switch_freq = 11,
>  	.cabc = false,
>  	.external_pfet = false,
> +	.auto_detection_enabled = false,
>  };
>  
>  static const u32 wled3_boost_i_limit_values[] = {
> @@ -676,6 +1021,7 @@ static int wled_configure(struct wled *wled, int version)
>  		{ "qcom,ext-gen", &cfg->ext_gen, },
>  		{ "qcom,cabc", &cfg->cabc, },
>  		{ "qcom,external-pfet", &cfg->external_pfet, },
> +		{ "qcom,auto-string-detection", &cfg->auto_detection_enabled, },
>  	};
>  
>  	prop_addr = of_get_address(dev->of_node, 0, NULL, NULL);
> @@ -796,6 +1142,40 @@ static int wled_configure_short_irq(struct wled *wled,
>  	return rc;
>  }
>  
> +static int wled_configure_ovp_irq(struct wled *wled,
> +				  struct platform_device *pdev)
> +{
> +	int rc;
> +	u32 val;
> +
> +	wled->ovp_irq = platform_get_irq_byname(pdev, "ovp");
> +	if (wled->ovp_irq < 0) {
> +		dev_dbg(&pdev->dev, "ovp irq is not used\n");

I assume this is optional.  What happens if no IRQ is provided?

If, for instance, polling mode is enabled, maybe something like this
would be better?

      dev_warn(&pdev->dev, "No IRQ found, falling back to polling mode\n");

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

  parent reply	other threads:[~2019-10-17 12:27 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-16 10:13 [PATCH V7 0/6] backlight: qcom-wled: Support for QCOM wled driver Kiran Gunda
2019-10-16 10:13 ` [PATCH V7 1/6] backlight: qcom-wled: Add new properties for PMI8998 Kiran Gunda
2019-10-16 10:13 ` [PATCH V7 2/6] backlight: qcom-wled: Rename PM8941* to WLED3 Kiran Gunda
2019-10-16 10:25   ` Kiran Gunda
2019-10-16 10:13 ` [PATCH V7 3/6] backlight: qcom-wled: Restructure the driver for WLED3 Kiran Gunda
2019-10-16 10:25   ` Kiran Gunda
2019-10-16 10:13 ` [PATCH V7 4/6] backlight: qcom-wled: Add support for WLED4 peripheral Kiran Gunda
2019-10-16 10:25   ` Kiran Gunda
2019-10-17 11:06   ` Daniel Thompson
2019-10-17 11:06     ` Daniel Thompson
2019-10-17 11:06     ` Daniel Thompson
2019-10-17 12:27     ` kgunda
2019-10-17 12:39       ` kgunda
2019-10-16 10:13 ` [PATCH V7 5/6] backlight: qcom-wled: add support for short circuit handling Kiran Gunda
2019-10-16 10:25   ` Kiran Gunda
2019-10-17 11:09   ` Daniel Thompson
2019-10-17 11:09     ` Daniel Thompson
2019-10-17 12:30     ` kgunda
2019-10-17 12:42       ` kgunda
2019-10-16 10:13 ` [PATCH V7 6/6] backlight: qcom-wled: Add auto string detection logic Kiran Gunda
2019-10-16 10:25   ` Kiran Gunda
2019-10-17 11:29   ` Daniel Thompson
2019-10-17 11:29     ` Daniel Thompson
2019-10-17 12:17     ` kgunda
2019-10-17 12:29       ` kgunda
2019-10-17 13:39       ` Daniel Thompson
2019-10-17 13:39         ` Daniel Thompson
2019-10-17 13:39         ` Daniel Thompson
2019-10-18  6:42         ` kgunda
2019-10-18  6:54           ` kgunda
2019-10-17 12:26   ` Lee Jones [this message]
2019-10-17 12:26     ` Lee Jones
2019-10-17 13:09     ` kgunda
2019-10-17 13:21       ` kgunda
2019-10-17 13:30       ` Lee Jones
2019-10-17 13:30         ` Lee Jones
2019-10-18  5:03         ` kgunda
2019-10-18  5:15           ` kgunda

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=20191017122653.GO4365@dell \
    --to=lee.jones@linaro.org \
    --cc=agross@kernel.org \
    --cc=b.zolnierkie@samsung.com \
    --cc=bjorn.andersson@linaro.org \
    --cc=daniel.thompson@linaro.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jacek.anaszewski@gmail.com \
    --cc=jingoohan1@gmail.com \
    --cc=kgunda@codeaurora.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=pavel@ucw.cz \
    --cc=robh+dt@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.