All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Ripard <maxime.ripard@bootlin.com>
To: Stefan Mavrodiev <stefan@olimex.com>
Cc: Jacek Anaszewski <jacek.anaszewski@gmail.com>,
	Pavel Machek <pavel@ucw.cz>, Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>, Chen-Yu Tsai <wens@csie.org>,
	Lee Jones <lee.jones@linaro.org>,
	"open list:LED SUBSYSTEM" <linux-leds@vger.kernel.org>,
	"open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS"
	<devicetree@vger.kernel.org>,
	"open list:X-POWERS MULTIFUNCTION PMIC DEVICE DRIVERS"
	<linux-kernel@vger.kernel.org>,
	"moderated list:ARM/Allwinner sunXi SoC support"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v2 1/8] leds: Add support for AXP20X CHGLED
Date: Fri, 15 Feb 2019 16:57:32 +0100	[thread overview]
Message-ID: <20190215155732.nmtshldcjk2qyhx4@flea> (raw)
In-Reply-To: <20190215115013.11098-2-stefan@olimex.com>

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

Hi Stefan,

Thanks for working on this.

On Fri, Feb 15, 2019 at 01:50:06PM +0200, Stefan Mavrodiev wrote:
> +static ssize_t control_show(struct device *dev, struct device_attribute *attr,
> +			    char *buf)
> +{
> +	struct led_classdev *cdev = dev_get_drvdata(dev);
> +	struct axp20x_led *priv = to_axp20x_led(cdev);
> +
> +	return sprintf(buf, "%u\n", priv->ctrl);
> +}
> +
> +static ssize_t control_store(struct device *dev, struct device_attribute *attr,
> +			     const char *buf, size_t size)
> +{
> +	struct led_classdev *cdev = dev_get_drvdata(dev);
> +	struct axp20x_led *priv = to_axp20x_led(cdev);
> +	unsigned long val;
> +	int ret;
> +
> +	ret = kstrtoul(buf, 0, &val);
> +	if (ret)
> +		return ret;
> +
> +	/**
> +	 * Supported values are:
> +	 *   - 0 : Manual control
> +	 *   - 1 : Charger control
> +	 */
> +	if (val > 1)
> +		return -EINVAL;
> +
> +	priv->ctrl = val;
> +
> +	return axp20x_led_setup(priv) ? : size;
> +}
> +static DEVICE_ATTR_RW(control);
> +
> +static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
> +			 char *buf)
> +{
> +	struct led_classdev *cdev = dev_get_drvdata(dev);
> +	struct axp20x_led *priv = to_axp20x_led(cdev);
> +
> +	return sprintf(buf, "%u\n", priv->mode);
> +}
> +
> +static ssize_t mode_store(struct device *dev, struct device_attribute *attr,
> +			  const char *buf, size_t size)
> +{
> +	struct led_classdev *cdev = dev_get_drvdata(dev);
> +	struct axp20x_led *priv = to_axp20x_led(cdev);
> +	unsigned long val;
> +	int ret;
> +
> +	ret = kstrtoul(buf, 0, &val);
> +	if (ret)
> +		return ret;
> +	/**
> +	 * Supported values are:
> +	 *   - 0 : Mode A
> +	 *   - 1 : Mode B
> +	 */
> +	if (val > 1)
> +		return -EINVAL;
> +
> +	priv->mode = val;
> +
> +	return axp20x_led_setup(priv) ? : size;
> +}
> +static DEVICE_ATTR_RW(mode);
> +
> +static struct attribute *axp20x_led_attrs[] = {
> +	&dev_attr_control.attr,
> +	&dev_attr_mode.attr,
> +	NULL,
> +};
> +ATTRIBUTE_GROUPS(axp20x_led);

I can't really say whether adding sysfs handles for this is the right
thing to do, but if it is you should document the interface.

> +	if (!of_property_read_u8(np, "x-powers,charger-mode", &value)) {
> +		priv->ctrl = AXP20X_CHGLED_CTRL_CHARGER;
> +		priv->mode = (value < 2) ? value : 0;
> +	} else {
> +		priv->ctrl = AXP20X_CHGLED_CTRL_MANUAL;
> +	}

I'm not sure we want to make this a property of the device
tree. Changing the device tree isn't an option for some users, so we
need to make sure we can change it even if we can't change the device
tree.

A kernel module is one option, but the other reviewers might have some
alternatives.

> +	str = of_get_property(np, "default-state", NULL);
> +	if (str) {
> +		if (!strcmp(str, "keep")) {
> +			ret = axp20x_led_brightness_get(&priv->cdev);
> +			if (ret < 0)
> +				return ret;
> +			priv->cdev.brightness = ret;
> +		} else if (!strcmp(str, "on")) {
> +			ret = axp20x_led_brightness_set_blocking(&priv->cdev,
> +								 LED_FULL);
> +		} else  {
> +			ret = axp20x_led_brightness_set_blocking(&priv->cdev,
> +								 LED_OFF);
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id axp20x_led_of_match[] = {
> +	{ .compatible = "x-powers,axp20x-led" },

Having a wildcard in the compatible isn't great, since it doesn't
really allow you to identify which part it is you're actually using,
and that wildcard might become inconsistent at some point.

You'd better use axp209-led (but the name of the driver is fine).

> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, axp20x_led_of_match);
> +
> +static int axp20x_led_probe(struct platform_device *pdev)
> +{
> +	struct axp20x_led *priv;
> +	int ret;
> +
> +	if (!of_device_is_available(pdev->dev.of_node))
> +		return -ENODEV;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_led),
> +			    GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->axp20x = dev_get_drvdata(pdev->dev.parent);
> +	if (!priv->axp20x) {
> +		dev_err(&pdev->dev, "Failed to get parent data\n");
> +		return -ENXIO;
> +	}
> +
> +	mutex_init(&priv->lock);
> +
> +	priv->cdev.brightness_set_blocking = axp20x_led_brightness_set_blocking;
> +	priv->cdev.brightness_get = axp20x_led_brightness_get;
> +	priv->cdev.groups = axp20x_led_groups;
> +
> +	ret = axp20x_led_parse_dt(priv, pdev->dev.of_node);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to set parameters\n");
> +		return ret;
> +	}
> +
> +	/**
> +	 * For some reason in AXP209 the bit that controls CHGLED is with
> +	 * inverted logic compared to all other PMICs.
> +	 * If the PMIC is actually AXP209, set inverted flag and later use it
> +	 * when configuring the LED.
> +	 */
> +	if (priv->axp20x->variant == AXP209_ID)
> +		priv->ctrl_inverted = 1;

This should be matched on the compatible.

Thanks!
Maxime

-- 
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Maxime Ripard <maxime.ripard@bootlin.com>
To: Stefan Mavrodiev <stefan@olimex.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
	"open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS"
	<devicetree@vger.kernel.org>,
	"open list:X-POWERS MULTIFUNCTION PMIC DEVICE DRIVERS"
	<linux-kernel@vger.kernel.org>, Chen-Yu Tsai <wens@csie.org>,
	Rob Herring <robh+dt@kernel.org>,
	Jacek Anaszewski <jacek.anaszewski@gmail.com>,
	Pavel Machek <pavel@ucw.cz>, Lee Jones <lee.jones@linaro.org>,
	"open list:LED SUBSYSTEM" <linux-leds@vger.kernel.org>,
	"moderated list:ARM/Allwinner sunXi SoC support"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v2 1/8] leds: Add support for AXP20X CHGLED
Date: Fri, 15 Feb 2019 16:57:32 +0100	[thread overview]
Message-ID: <20190215155732.nmtshldcjk2qyhx4@flea> (raw)
In-Reply-To: <20190215115013.11098-2-stefan@olimex.com>


[-- Attachment #1.1: Type: text/plain, Size: 5042 bytes --]

Hi Stefan,

Thanks for working on this.

On Fri, Feb 15, 2019 at 01:50:06PM +0200, Stefan Mavrodiev wrote:
> +static ssize_t control_show(struct device *dev, struct device_attribute *attr,
> +			    char *buf)
> +{
> +	struct led_classdev *cdev = dev_get_drvdata(dev);
> +	struct axp20x_led *priv = to_axp20x_led(cdev);
> +
> +	return sprintf(buf, "%u\n", priv->ctrl);
> +}
> +
> +static ssize_t control_store(struct device *dev, struct device_attribute *attr,
> +			     const char *buf, size_t size)
> +{
> +	struct led_classdev *cdev = dev_get_drvdata(dev);
> +	struct axp20x_led *priv = to_axp20x_led(cdev);
> +	unsigned long val;
> +	int ret;
> +
> +	ret = kstrtoul(buf, 0, &val);
> +	if (ret)
> +		return ret;
> +
> +	/**
> +	 * Supported values are:
> +	 *   - 0 : Manual control
> +	 *   - 1 : Charger control
> +	 */
> +	if (val > 1)
> +		return -EINVAL;
> +
> +	priv->ctrl = val;
> +
> +	return axp20x_led_setup(priv) ? : size;
> +}
> +static DEVICE_ATTR_RW(control);
> +
> +static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
> +			 char *buf)
> +{
> +	struct led_classdev *cdev = dev_get_drvdata(dev);
> +	struct axp20x_led *priv = to_axp20x_led(cdev);
> +
> +	return sprintf(buf, "%u\n", priv->mode);
> +}
> +
> +static ssize_t mode_store(struct device *dev, struct device_attribute *attr,
> +			  const char *buf, size_t size)
> +{
> +	struct led_classdev *cdev = dev_get_drvdata(dev);
> +	struct axp20x_led *priv = to_axp20x_led(cdev);
> +	unsigned long val;
> +	int ret;
> +
> +	ret = kstrtoul(buf, 0, &val);
> +	if (ret)
> +		return ret;
> +	/**
> +	 * Supported values are:
> +	 *   - 0 : Mode A
> +	 *   - 1 : Mode B
> +	 */
> +	if (val > 1)
> +		return -EINVAL;
> +
> +	priv->mode = val;
> +
> +	return axp20x_led_setup(priv) ? : size;
> +}
> +static DEVICE_ATTR_RW(mode);
> +
> +static struct attribute *axp20x_led_attrs[] = {
> +	&dev_attr_control.attr,
> +	&dev_attr_mode.attr,
> +	NULL,
> +};
> +ATTRIBUTE_GROUPS(axp20x_led);

I can't really say whether adding sysfs handles for this is the right
thing to do, but if it is you should document the interface.

> +	if (!of_property_read_u8(np, "x-powers,charger-mode", &value)) {
> +		priv->ctrl = AXP20X_CHGLED_CTRL_CHARGER;
> +		priv->mode = (value < 2) ? value : 0;
> +	} else {
> +		priv->ctrl = AXP20X_CHGLED_CTRL_MANUAL;
> +	}

I'm not sure we want to make this a property of the device
tree. Changing the device tree isn't an option for some users, so we
need to make sure we can change it even if we can't change the device
tree.

A kernel module is one option, but the other reviewers might have some
alternatives.

> +	str = of_get_property(np, "default-state", NULL);
> +	if (str) {
> +		if (!strcmp(str, "keep")) {
> +			ret = axp20x_led_brightness_get(&priv->cdev);
> +			if (ret < 0)
> +				return ret;
> +			priv->cdev.brightness = ret;
> +		} else if (!strcmp(str, "on")) {
> +			ret = axp20x_led_brightness_set_blocking(&priv->cdev,
> +								 LED_FULL);
> +		} else  {
> +			ret = axp20x_led_brightness_set_blocking(&priv->cdev,
> +								 LED_OFF);
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id axp20x_led_of_match[] = {
> +	{ .compatible = "x-powers,axp20x-led" },

Having a wildcard in the compatible isn't great, since it doesn't
really allow you to identify which part it is you're actually using,
and that wildcard might become inconsistent at some point.

You'd better use axp209-led (but the name of the driver is fine).

> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, axp20x_led_of_match);
> +
> +static int axp20x_led_probe(struct platform_device *pdev)
> +{
> +	struct axp20x_led *priv;
> +	int ret;
> +
> +	if (!of_device_is_available(pdev->dev.of_node))
> +		return -ENODEV;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_led),
> +			    GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->axp20x = dev_get_drvdata(pdev->dev.parent);
> +	if (!priv->axp20x) {
> +		dev_err(&pdev->dev, "Failed to get parent data\n");
> +		return -ENXIO;
> +	}
> +
> +	mutex_init(&priv->lock);
> +
> +	priv->cdev.brightness_set_blocking = axp20x_led_brightness_set_blocking;
> +	priv->cdev.brightness_get = axp20x_led_brightness_get;
> +	priv->cdev.groups = axp20x_led_groups;
> +
> +	ret = axp20x_led_parse_dt(priv, pdev->dev.of_node);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to set parameters\n");
> +		return ret;
> +	}
> +
> +	/**
> +	 * For some reason in AXP209 the bit that controls CHGLED is with
> +	 * inverted logic compared to all other PMICs.
> +	 * If the PMIC is actually AXP209, set inverted flag and later use it
> +	 * when configuring the LED.
> +	 */
> +	if (priv->axp20x->variant == AXP209_ID)
> +		priv->ctrl_inverted = 1;

This should be matched on the compatible.

Thanks!
Maxime

-- 
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2019-02-15 15:57 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-15 11:50 [PATCH v2 0/8] leds: Add AXP20X CHGLED Stefan Mavrodiev
2019-02-15 11:50 ` Stefan Mavrodiev
2019-02-15 11:50 ` Stefan Mavrodiev
2019-02-15 11:50 ` [PATCH v2 1/8] leds: Add support for " Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 14:07   ` Stefan Mavrodiev
2019-02-15 14:07     ` Stefan Mavrodiev
2019-02-15 14:07     ` Stefan Mavrodiev
2019-02-15 15:57   ` Maxime Ripard [this message]
2019-02-15 15:57     ` Maxime Ripard
2019-02-15 15:57     ` Maxime Ripard
2019-02-15 18:32     ` Pavel Machek
2019-02-15 18:32       ` Pavel Machek
2019-02-15 18:32       ` Pavel Machek
2019-02-19  7:42       ` Stefan Mavrodiev
2019-02-19  7:42         ` Stefan Mavrodiev
2019-02-19  7:42         ` Stefan Mavrodiev
2019-02-15 11:50 ` [PATCH v2 2/8] mfd: axp20x: Add axp20x-led cell Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-03-25 10:01   ` Lee Jones
2019-03-25 10:01     ` Lee Jones
2019-03-25 10:01     ` Lee Jones
2019-02-15 11:50 ` [PATCH v2 3/8] dt-bindings: leds: Add binding for axp20x-led device driver Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-22 19:51   ` Rob Herring
2019-02-22 19:51     ` Rob Herring
2019-02-22 19:51     ` Rob Herring
2019-02-23 13:02     ` Jacek Anaszewski
2019-02-23 13:02       ` Jacek Anaszewski
2019-02-23 13:02       ` Jacek Anaszewski
2019-02-15 11:50 ` [PATCH v2 4/8] arm64: dts: allwinner: axp803: add charge led node Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50 ` [PATCH v2 5/8] arm64: dts: allwinner: Enable AXP803 CHGLED for Olimex boards Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 18:49   ` Pavel Machek
2019-02-15 18:49     ` Pavel Machek
2019-02-15 18:49     ` Pavel Machek
2019-02-19  7:43     ` Stefan Mavrodiev
2019-02-19  7:43       ` Stefan Mavrodiev
2019-02-19  7:43       ` Stefan Mavrodiev
2019-02-15 11:50 ` [PATCH v2 6/8] arm: dts: axpxx: add charge led node Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50 ` [PATCH v2 7/8] ARM: dts: sun7i: Enable AXP209 CHGLED for Olimex boards Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50 ` [PATCH v2 8/8] ARM: dts: sun8i: a33: Enable AXP223 CHGLED for A33-OLinuXino Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev
2019-02-15 11:50   ` Stefan Mavrodiev

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=20190215155732.nmtshldcjk2qyhx4@flea \
    --to=maxime.ripard@bootlin.com \
    --cc=devicetree@vger.kernel.org \
    --cc=jacek.anaszewski@gmail.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.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 \
    --cc=stefan@olimex.com \
    --cc=wens@csie.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.