devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
@ 2019-05-05 20:00 oss
  2019-05-05 20:00 ` [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver oss
  2019-05-06 16:21 ` [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED Rob Herring
  0 siblings, 2 replies; 28+ messages in thread
From: oss @ 2019-05-05 20:00 UTC (permalink / raw)
  To: linux-leds, devicetree, Jacek Anaszewski, Pavel Machek
  Cc: Dan Murphy, Rob Herring, Mark Rutland, Christian Mauderer

From: Christian Mauderer <oss@c-mauderer.de>

This patch adds the binding documentation for a simple SPI based LED
controller which use only one byte for setting the brightness.

Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
---

Changes compared to v2:
- None

Changes compared to v1:
- rename ubnt-spi to leds-spi-byte
- rename "ubnt-spi,off_bright" and "ubnt-spi,max_bright" to
  "leds-spi-byte,off-value" and "leds-spi-byte,max-value" and mark them required
- rename led-controller node to "led-controller"
- extend description
- remove SPI controller
- use "white:status" for the example label


 .../bindings/leds/leds-spi-byte.txt           | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-spi-byte.txt

diff --git a/Documentation/devicetree/bindings/leds/leds-spi-byte.txt b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
new file mode 100644
index 000000000000..1dd6ab03a56d
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
@@ -0,0 +1,47 @@
+* Single Byte SPI LED Device Driver.
+
+The driver can be used for controllers with a very simple SPI protocol: Only one
+byte will be sent. The value of the byte can be any value between the off-value
+and max-value defined in the properties.
+
+One example where the driver can be used is the controller in Ubiquiti airCube
+ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX
+8F26E611LA) that has been programmed to control the single LED of the device.
+The controller supports four modes depending on the highest two bits in a byte:
+One setting for brightness, the other three provide different blink patterns.
+With the leds-spi-byte driver a basic support for the brightness mode of that
+controller can be easily achieved by setting the minimum and maximum to the
+brightness modes minimum and maximum byte value.
+
+Required properties:
+- compatible:		Should be "leds-spi-byte".
+
+Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
+apply. In particular, "reg" and "spi-max-frequency" properties must be given.
+
+The driver currently only supports one LED. The properties of the LED are
+configured in a sub-node in the device node.
+
+LED sub-node properties:
+- label:
+	see Documentation/devicetree/bindings/leds/common.txt
+- leds-spi-byte,off-value:
+	The SPI byte value that should be sent to switch the LED off. Has to be
+	smaller than max-value. Range: 0 to 254.
+- leds-spi-byte,max-value:
+	The SPI byte value that should be sent to set the LED to the maximum
+	brightness. Has to be bigger than off-value. Range: 1 to 255.
+
+Example:
+
+led-controller@0 {
+	compatible = "leds-spi-byte";
+	reg = <0>;
+	spi-max-frequency = <100000>;
+
+	led {
+		label = "white:status";
+		leds-spi-byte,off-value = /bits/ 8 <0>;
+		leds-spi-byte,max-value = /bits/ 8 <63>;
+	};
+};
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-05 20:00 [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED oss
@ 2019-05-05 20:00 ` oss
  2019-05-05 20:09   ` Jacek Anaszewski
  2019-05-06 12:05   ` Dan Murphy
  2019-05-06 16:21 ` [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED Rob Herring
  1 sibling, 2 replies; 28+ messages in thread
From: oss @ 2019-05-05 20:00 UTC (permalink / raw)
  To: linux-leds, devicetree, Jacek Anaszewski, Pavel Machek
  Cc: Dan Murphy, Rob Herring, Mark Rutland, Christian Mauderer

From: Christian Mauderer <oss@c-mauderer.de>

This driver adds support for simple SPI based LED controller which use
only one byte for setting the brightness.

Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
---

Changes compared to v2:
- use "if (ret)" instead of "if (ret != 0)"
- don't initialize ldev-fields with zero
- use devm_led_classdev_register instead of led_classdev_register
- check for error instead of good case with the last if in spi_byte_probe

Changes compared to v1:
- rename ubnt-spi to leds-spi-byte
- rework probe to get all parameters before allocating anything -> error checks
  all collected together and initializing all fields of the device structure is
  more obvious
- fix some unsteady indentations during variable declaration
- rework comment with protocol explanation
- handle case of off_bright > max_bright
- fix spelling in commit message
- mutex_destroy in remove
- change label to use either use the given one without a prefix or a default one


 drivers/leds/Kconfig         |  12 ++++
 drivers/leds/Makefile        |   1 +
 drivers/leds/leds-spi-byte.c | 134 +++++++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 drivers/leds/leds-spi-byte.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index a72f97fca57b..0866c55e8004 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -766,6 +766,18 @@ config LEDS_NIC78BX
 	  To compile this driver as a module, choose M here: the module
 	  will be called leds-nic78bx.
 
+config LEDS_SPI_BYTE
+	tristate "LED support for SPI LED controller with a single byte"
+	depends on LEDS_CLASS
+	depends on SPI
+	depends on OF
+	help
+	  This option enables support for LED controller which use a single byte
+	  for controlling the brightness. The minimum and maximum value of the
+	  byte can be configured via a device tree. The driver can be used for
+	  example for the microcontroller based LED controller in the Ubiquiti
+	  airCube ISP devices.
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 4c1b0054f379..1786d7e2c236 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_LEDS_PM8058)		+= leds-pm8058.o
 obj-$(CONFIG_LEDS_MLXCPLD)		+= leds-mlxcpld.o
 obj-$(CONFIG_LEDS_MLXREG)		+= leds-mlxreg.o
 obj-$(CONFIG_LEDS_NIC78BX)		+= leds-nic78bx.o
+obj-$(CONFIG_LEDS_SPI_BYTE)		+= leds-spi-byte.o
 obj-$(CONFIG_LEDS_MT6323)		+= leds-mt6323.o
 obj-$(CONFIG_LEDS_LM3692X)		+= leds-lm3692x.o
 obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c
new file mode 100644
index 000000000000..8170b2da497a
--- /dev/null
+++ b/drivers/leds/leds-spi-byte.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de>
+
+/*
+ * The driver can be used for controllers with a very simple SPI protocol: Only
+ * one byte between an off and a max value (defined by devicetree) will be sent.
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mutex.h>
+#include <uapi/linux/uleds.h>
+
+struct spi_byte_led {
+	struct led_classdev	ldev;
+	struct spi_device	*spi;
+	char			name[LED_MAX_NAME_SIZE];
+	struct mutex		mutex;
+	u8			off_value;
+	u8			max_value;
+};
+
+static int spi_byte_brightness_set_blocking(struct led_classdev *dev,
+					    enum led_brightness brightness)
+{
+	struct spi_byte_led *led = container_of(dev, struct spi_byte_led, ldev);
+	u8 value;
+	int ret;
+
+	value = (u8) brightness + led->off_value;
+
+	mutex_lock(&led->mutex);
+	ret = spi_write(led->spi, &value, sizeof(value));
+	mutex_unlock(&led->mutex);
+
+	return ret;
+}
+
+static int spi_byte_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct device_node *child;
+	struct spi_byte_led *led;
+	int ret;
+	const char *default_name = "leds-spi-byte::";
+	const char *name;
+	u8 off_value;
+	u8 max_value;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	if (of_get_child_count(dev->of_node) != 1) {
+		dev_err(dev, "Device must have exactly one LED sub-node.");
+		return -EINVAL;
+	}
+	child = of_get_next_child(dev->of_node, NULL);
+
+	ret = of_property_read_string(child, "label", &name);
+	if (ret)
+		name = default_name;
+
+	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value);
+	if (ret) {
+		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value);
+	if (ret) {
+		dev_err(dev, "LED node needs a leds-spi-byte,max-value.");
+		return -EINVAL;
+	}
+
+	if (off_value >= max_value) {
+		dev_err(dev, "off-value has to be smaller than max-value.");
+		return -EINVAL;
+	}
+
+	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
+	if (!led)
+		return -ENOMEM;
+
+	led->spi = spi;
+	strlcpy(led->name, name, sizeof(led->name));
+	mutex_init(&led->mutex);
+	led->off_value = off_value;
+	led->max_value = max_value;
+	led->ldev.name = led->name;
+	led->ldev.max_brightness = led->max_value - led->off_value;
+	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
+	ret = devm_led_classdev_register(&spi->dev, &led->ldev);
+	if (ret)
+		return ret;
+
+	spi_set_drvdata(spi, led);
+
+	return 0;
+}
+
+static int spi_byte_remove(struct spi_device *spi)
+{
+	struct spi_byte_led	*led = spi_get_drvdata(spi);
+
+	led_classdev_unregister(&led->ldev);
+	mutex_destroy(&led->mutex);
+
+	return 0;
+}
+
+static const struct of_device_id spi_byte_dt_ids[] = {
+	{ .compatible = "leds-spi-byte", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, spi_byte_dt_ids);
+
+static struct spi_driver spi_byte_driver = {
+	.probe		= spi_byte_probe,
+	.remove		= spi_byte_remove,
+	.driver = {
+		.name		= KBUILD_MODNAME,
+		.of_match_table	= spi_byte_dt_ids,
+	},
+};
+
+module_spi_driver(spi_byte_driver);
+
+MODULE_AUTHOR("Christian Mauderer <oss@c-mauderer.de>");
+MODULE_DESCRIPTION("single byte SPI LED driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:leds-spi-byte");
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-05 20:00 ` [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver oss
@ 2019-05-05 20:09   ` Jacek Anaszewski
  2019-05-05 20:14     ` Christian Mauderer
  2019-05-06 12:05   ` Dan Murphy
  1 sibling, 1 reply; 28+ messages in thread
From: Jacek Anaszewski @ 2019-05-05 20:09 UTC (permalink / raw)
  To: oss, linux-leds, devicetree, Pavel Machek
  Cc: Dan Murphy, Rob Herring, Mark Rutland

Christian,

Thank you for the update. One thing left after switching
to devm API. Please refer below to the remove op.

On 5/5/19 10:00 PM, oss@c-mauderer.de wrote:
> From: Christian Mauderer <oss@c-mauderer.de>
> 
> This driver adds support for simple SPI based LED controller which use
> only one byte for setting the brightness.
> 
> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
> ---
> 
> Changes compared to v2:
> - use "if (ret)" instead of "if (ret != 0)"
> - don't initialize ldev-fields with zero
> - use devm_led_classdev_register instead of led_classdev_register
> - check for error instead of good case with the last if in spi_byte_probe
> 
> Changes compared to v1:
> - rename ubnt-spi to leds-spi-byte
> - rework probe to get all parameters before allocating anything -> error checks
>    all collected together and initializing all fields of the device structure is
>    more obvious
> - fix some unsteady indentations during variable declaration
> - rework comment with protocol explanation
> - handle case of off_bright > max_bright
> - fix spelling in commit message
> - mutex_destroy in remove
> - change label to use either use the given one without a prefix or a default one
> 
> 
>   drivers/leds/Kconfig         |  12 ++++
>   drivers/leds/Makefile        |   1 +
>   drivers/leds/leds-spi-byte.c | 134 +++++++++++++++++++++++++++++++++++
>   3 files changed, 147 insertions(+)
>   create mode 100644 drivers/leds/leds-spi-byte.c

[...]
> +
> +static int spi_byte_remove(struct spi_device *spi)
> +{
> +	struct spi_byte_led	*led = spi_get_drvdata(spi);
> +
> +	led_classdev_unregister(&led->ldev);

This is now not needed - devm, means "device managed", i.e.
all resources claimed with it will be automatically reclaimed
on device destruction.

> +	mutex_destroy(&led->mutex);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id spi_byte_dt_ids[] = {
> +	{ .compatible = "leds-spi-byte", },
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(of, spi_byte_dt_ids);
> +
> +static struct spi_driver spi_byte_driver = {
> +	.probe		= spi_byte_probe,
> +	.remove		= spi_byte_remove,
> +	.driver = {
> +		.name		= KBUILD_MODNAME,
> +		.of_match_table	= spi_byte_dt_ids,
> +	},
> +};
> +
> +module_spi_driver(spi_byte_driver);
> +
> +MODULE_AUTHOR("Christian Mauderer <oss@c-mauderer.de>");
> +MODULE_DESCRIPTION("single byte SPI LED driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("spi:leds-spi-byte");
> 

-- 
Best regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-05 20:09   ` Jacek Anaszewski
@ 2019-05-05 20:14     ` Christian Mauderer
  0 siblings, 0 replies; 28+ messages in thread
From: Christian Mauderer @ 2019-05-05 20:14 UTC (permalink / raw)
  To: Jacek Anaszewski, linux-leds, devicetree, Pavel Machek
  Cc: Dan Murphy, Rob Herring, Mark Rutland

On 05/05/2019 22:09, Jacek Anaszewski wrote:
> Christian,
> 
> Thank you for the update. One thing left after switching
> to devm API. Please refer below to the remove op.
> 
> On 5/5/19 10:00 PM, oss@c-mauderer.de wrote:
>> From: Christian Mauderer <oss@c-mauderer.de>
>>
>> This driver adds support for simple SPI based LED controller which use
>> only one byte for setting the brightness.
>>
>> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
>> ---
>>
>> Changes compared to v2:
>> - use "if (ret)" instead of "if (ret != 0)"
>> - don't initialize ldev-fields with zero
>> - use devm_led_classdev_register instead of led_classdev_register
>> - check for error instead of good case with the last if in spi_byte_probe
>>
>> Changes compared to v1:
>> - rename ubnt-spi to leds-spi-byte
>> - rework probe to get all parameters before allocating anything ->
>> error checks
>>    all collected together and initializing all fields of the device
>> structure is
>>    more obvious
>> - fix some unsteady indentations during variable declaration
>> - rework comment with protocol explanation
>> - handle case of off_bright > max_bright
>> - fix spelling in commit message
>> - mutex_destroy in remove
>> - change label to use either use the given one without a prefix or a
>> default one
>>
>>
>>   drivers/leds/Kconfig         |  12 ++++
>>   drivers/leds/Makefile        |   1 +
>>   drivers/leds/leds-spi-byte.c | 134 +++++++++++++++++++++++++++++++++++
>>   3 files changed, 147 insertions(+)
>>   create mode 100644 drivers/leds/leds-spi-byte.c
> 
> [...]
>> +
>> +static int spi_byte_remove(struct spi_device *spi)
>> +{
>> +    struct spi_byte_led    *led = spi_get_drvdata(spi);
>> +
>> +    led_classdev_unregister(&led->ldev);
> 
> This is now not needed - devm, means "device managed", i.e.
> all resources claimed with it will be automatically reclaimed
> on device destruction.
> 

Thanks for the hint. I've read that the devm functions are some "free
automatically" functions. But I haven't drawn the conclusion that I have
to remove this function. Seems I still need to learn a lot about the
Linux API.

I'll wait for further feedback over night and then remove it in a v4
tomorrow. Otherwise I'll spam the list with lots of new versions.

>> +    mutex_destroy(&led->mutex);
>> +
>> +    return 0;
>> +}
>> +
>> +static const struct of_device_id spi_byte_dt_ids[] = {
>> +    { .compatible = "leds-spi-byte", },
>> +    {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, spi_byte_dt_ids);
>> +
>> +static struct spi_driver spi_byte_driver = {
>> +    .probe        = spi_byte_probe,
>> +    .remove        = spi_byte_remove,
>> +    .driver = {
>> +        .name        = KBUILD_MODNAME,
>> +        .of_match_table    = spi_byte_dt_ids,
>> +    },
>> +};
>> +
>> +module_spi_driver(spi_byte_driver);
>> +
>> +MODULE_AUTHOR("Christian Mauderer <oss@c-mauderer.de>");
>> +MODULE_DESCRIPTION("single byte SPI LED driver");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_ALIAS("spi:leds-spi-byte");
>>
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-05 20:00 ` [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver oss
  2019-05-05 20:09   ` Jacek Anaszewski
@ 2019-05-06 12:05   ` Dan Murphy
  2019-05-06 12:59     ` Christian Mauderer
  1 sibling, 1 reply; 28+ messages in thread
From: Dan Murphy @ 2019-05-06 12:05 UTC (permalink / raw)
  To: oss, linux-leds, devicetree, Jacek Anaszewski, Pavel Machek
  Cc: Rob Herring, Mark Rutland

Christian

On 5/5/19 3:00 PM, oss@c-mauderer.de wrote:
> From: Christian Mauderer <oss@c-mauderer.de>
> 
> This driver adds support for simple SPI based LED controller which use
> only one byte for setting the brightness.
> 
> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
> ---
> 
> Changes compared to v2:
> - use "if (ret)" instead of "if (ret != 0)"
> - don't initialize ldev-fields with zero
> - use devm_led_classdev_register instead of led_classdev_register
> - check for error instead of good case with the last if in spi_byte_probe
> 
> Changes compared to v1:
> - rename ubnt-spi to leds-spi-byte
> - rework probe to get all parameters before allocating anything -> error checks
>   all collected together and initializing all fields of the device structure is
>   more obvious
> - fix some unsteady indentations during variable declaration
> - rework comment with protocol explanation
> - handle case of off_bright > max_bright
> - fix spelling in commit message
> - mutex_destroy in remove
> - change label to use either use the given one without a prefix or a default one
> 
> 
>  drivers/leds/Kconfig         |  12 ++++
>  drivers/leds/Makefile        |   1 +
>  drivers/leds/leds-spi-byte.c | 134 +++++++++++++++++++++++++++++++++++
>  3 files changed, 147 insertions(+)
>  create mode 100644 drivers/leds/leds-spi-byte.c
> 
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index a72f97fca57b..0866c55e8004 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -766,6 +766,18 @@ config LEDS_NIC78BX
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called leds-nic78bx.
>  
> +config LEDS_SPI_BYTE
> +	tristate "LED support for SPI LED controller with a single byte"
> +	depends on LEDS_CLASS
> +	depends on SPI
> +	depends on OF
> +	help
> +	  This option enables support for LED controller which use a single byte
> +	  for controlling the brightness. The minimum and maximum value of the
> +	  byte can be configured via a device tree. The driver can be used for
> +	  example for the microcontroller based LED controller in the Ubiquiti
> +	  airCube ISP devices.
> +
>  comment "LED Triggers"
>  source "drivers/leds/trigger/Kconfig"
>  
> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
> index 4c1b0054f379..1786d7e2c236 100644
> --- a/drivers/leds/Makefile
> +++ b/drivers/leds/Makefile
> @@ -75,6 +75,7 @@ obj-$(CONFIG_LEDS_PM8058)		+= leds-pm8058.o
>  obj-$(CONFIG_LEDS_MLXCPLD)		+= leds-mlxcpld.o
>  obj-$(CONFIG_LEDS_MLXREG)		+= leds-mlxreg.o
>  obj-$(CONFIG_LEDS_NIC78BX)		+= leds-nic78bx.o
> +obj-$(CONFIG_LEDS_SPI_BYTE)		+= leds-spi-byte.o
>  obj-$(CONFIG_LEDS_MT6323)		+= leds-mt6323.o
>  obj-$(CONFIG_LEDS_LM3692X)		+= leds-lm3692x.o
>  obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
> diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c
> new file mode 100644
> index 000000000000..8170b2da497a
> --- /dev/null
> +++ b/drivers/leds/leds-spi-byte.c
> @@ -0,0 +1,134 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de>
> +
> +/*
> + * The driver can be used for controllers with a very simple SPI protocol: Only
> + * one byte between an off and a max value (defined by devicetree) will be sent.
> + */
> +
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/spi/spi.h>
> +#include <linux/mutex.h>
> +#include <uapi/linux/uleds.h>
> +
> +struct spi_byte_led {
> +	struct led_classdev	ldev;
> +	struct spi_device	*spi;
> +	char			name[LED_MAX_NAME_SIZE];
> +	struct mutex		mutex;
> +	u8			off_value;
> +	u8			max_value;
> +};
> +
> +static int spi_byte_brightness_set_blocking(struct led_classdev *dev,
> +					    enum led_brightness brightness)
> +{
> +	struct spi_byte_led *led = container_of(dev, struct spi_byte_led, ldev);
> +	u8 value;
> +	int ret;
> +
> +	value = (u8) brightness + led->off_value;
> +

Sorry if this has been addressed but the versions moved fast.

What is the purpose of adding the off_value?

If max is 63 and say off value is 1 then this will set brightness to 64 but that is not what the LED framework will send.
if you read the brightness.

Is it safe to assume that off_value would always be 0?


> +	mutex_lock(&led->mutex);
> +	ret = spi_write(led->spi, &value, sizeof(value));
> +	mutex_unlock(&led->mutex);
> +
> +	return ret;
> +}
> +
> +static int spi_byte_probe(struct spi_device *spi)
> +{
> +	struct device *dev = &spi->dev;
> +	struct device_node *child;
> +	struct spi_byte_led *led;
> +	int ret;
> +	const char *default_name = "leds-spi-byte::";
> +	const char *name;
> +	u8 off_value;
> +	u8 max_value;
> +
> +	if (!dev->of_node)
> +		return -ENODEV;
> +
> +	if (of_get_child_count(dev->of_node) != 1) {
> +		dev_err(dev, "Device must have exactly one LED sub-node.");
> +		return -EINVAL;
> +	}
> +	child = of_get_next_child(dev->of_node, NULL);
> +
> +	ret = of_property_read_string(child, "label", &name);
> +	if (ret)
> +		name = default_name;
> +
> +	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value);
> +	if (ret) {
> +		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value);
> +	if (ret) {
> +		dev_err(dev, "LED node needs a leds-spi-byte,max-value.");
> +		return -EINVAL;
> +	}
> +

You could probably allocate the led struct memory first and then pass in the address of those
variables as opposed to creating the stack variables.

	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
	if (!led)
		return -ENOMEM;

	ret = of_property_read_string(child, "label", &led->ldev.name);
	if (ret)
		led->ldev.name = default_name;

	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &led->off_value);
	if (ret) {
		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
		return -EINVAL;
	}
	.
	.
	.


> +	if (off_value >= max_value) {
> +		dev_err(dev, "off-value has to be smaller than max-value.");
> +		return -EINVAL;
> +	}
> +
> +	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
> +	if (!led)
> +		return -ENOMEM;
> +
> +	led->spi = spi;
> +	strlcpy(led->name, name, sizeof(led->name));
> +	mutex_init(&led->mutex);
> +	led->off_value = off_value;
> +	led->max_value = max_value;
> +	led->ldev.name = led->name;
> +	led->ldev.max_brightness = led->max_value - led->off_value;

Again not sure why this is needed.  This is changing the behavior of what max brightness value is defined in the DT.
And this is not documented in the DT doc.

max_value = 255 off_value = 254 meets all the criteria but then LED framework has max brightness is 1
But that is not what is described in the DT.

> +	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
> +	ret = devm_led_classdev_register(&spi->dev, &led->ldev);
> +	if (ret)
> +		return ret;
> +
> +	spi_set_drvdata(spi, led);

If you move this above the registration this can just become

return = devm_led_classdev_register(&spi->dev, &led->ldev);

> +
> +	return 0;
> +}
> +
> +static int spi_byte_remove(struct spi_device *spi)
> +{
> +	struct spi_byte_led	*led = spi_get_drvdata(spi);
> +
> +	led_classdev_unregister(&led->ldev);

Don't need this with devm call

Dan

<snip>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 12:05   ` Dan Murphy
@ 2019-05-06 12:59     ` Christian Mauderer
  2019-05-06 14:58       ` Dan Murphy
  0 siblings, 1 reply; 28+ messages in thread
From: Christian Mauderer @ 2019-05-06 12:59 UTC (permalink / raw)
  To: Dan Murphy, linux-leds, devicetree, Jacek Anaszewski,
	Pavel Machek
  Cc: Rob Herring, Mark Rutland

Hello Dan,

thanks for reviewing the patch.

On 06/05/2019 14:05, Dan Murphy wrote:
> Christian
> 
> On 5/5/19 3:00 PM, oss@c-mauderer.de wrote:
>> From: Christian Mauderer <oss@c-mauderer.de>
>>
>> This driver adds support for simple SPI based LED controller which use
>> only one byte for setting the brightness.
>>
>> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
>> ---
>>
>> Changes compared to v2:
>> - use "if (ret)" instead of "if (ret != 0)"
>> - don't initialize ldev-fields with zero
>> - use devm_led_classdev_register instead of led_classdev_register
>> - check for error instead of good case with the last if in spi_byte_probe
>>
>> Changes compared to v1:
>> - rename ubnt-spi to leds-spi-byte
>> - rework probe to get all parameters before allocating anything -> error checks
>>   all collected together and initializing all fields of the device structure is
>>   more obvious
>> - fix some unsteady indentations during variable declaration
>> - rework comment with protocol explanation
>> - handle case of off_bright > max_bright
>> - fix spelling in commit message
>> - mutex_destroy in remove
>> - change label to use either use the given one without a prefix or a default one
>>
>>
>>  drivers/leds/Kconfig         |  12 ++++
>>  drivers/leds/Makefile        |   1 +
>>  drivers/leds/leds-spi-byte.c | 134 +++++++++++++++++++++++++++++++++++
>>  3 files changed, 147 insertions(+)
>>  create mode 100644 drivers/leds/leds-spi-byte.c
>>
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index a72f97fca57b..0866c55e8004 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -766,6 +766,18 @@ config LEDS_NIC78BX
>>  	  To compile this driver as a module, choose M here: the module
>>  	  will be called leds-nic78bx.
>>  
>> +config LEDS_SPI_BYTE
>> +	tristate "LED support for SPI LED controller with a single byte"
>> +	depends on LEDS_CLASS
>> +	depends on SPI
>> +	depends on OF
>> +	help
>> +	  This option enables support for LED controller which use a single byte
>> +	  for controlling the brightness. The minimum and maximum value of the
>> +	  byte can be configured via a device tree. The driver can be used for
>> +	  example for the microcontroller based LED controller in the Ubiquiti
>> +	  airCube ISP devices.
>> +
>>  comment "LED Triggers"
>>  source "drivers/leds/trigger/Kconfig"
>>  
>> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
>> index 4c1b0054f379..1786d7e2c236 100644
>> --- a/drivers/leds/Makefile
>> +++ b/drivers/leds/Makefile
>> @@ -75,6 +75,7 @@ obj-$(CONFIG_LEDS_PM8058)		+= leds-pm8058.o
>>  obj-$(CONFIG_LEDS_MLXCPLD)		+= leds-mlxcpld.o
>>  obj-$(CONFIG_LEDS_MLXREG)		+= leds-mlxreg.o
>>  obj-$(CONFIG_LEDS_NIC78BX)		+= leds-nic78bx.o
>> +obj-$(CONFIG_LEDS_SPI_BYTE)		+= leds-spi-byte.o
>>  obj-$(CONFIG_LEDS_MT6323)		+= leds-mt6323.o
>>  obj-$(CONFIG_LEDS_LM3692X)		+= leds-lm3692x.o
>>  obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
>> diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c
>> new file mode 100644
>> index 000000000000..8170b2da497a
>> --- /dev/null
>> +++ b/drivers/leds/leds-spi-byte.c
>> @@ -0,0 +1,134 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de>
>> +
>> +/*
>> + * The driver can be used for controllers with a very simple SPI protocol: Only
>> + * one byte between an off and a max value (defined by devicetree) will be sent.
>> + */
>> +
>> +#include <linux/leds.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/spi/spi.h>
>> +#include <linux/mutex.h>
>> +#include <uapi/linux/uleds.h>
>> +
>> +struct spi_byte_led {
>> +	struct led_classdev	ldev;
>> +	struct spi_device	*spi;
>> +	char			name[LED_MAX_NAME_SIZE];
>> +	struct mutex		mutex;
>> +	u8			off_value;
>> +	u8			max_value;
>> +};
>> +
>> +static int spi_byte_brightness_set_blocking(struct led_classdev *dev,
>> +					    enum led_brightness brightness)
>> +{
>> +	struct spi_byte_led *led = container_of(dev, struct spi_byte_led, ldev);
>> +	u8 value;
>> +	int ret;
>> +
>> +	value = (u8) brightness + led->off_value;
>> +
> 
> Sorry if this has been addressed but the versions moved fast.
> 
> What is the purpose of adding the off_value?
> 
> If max is 63 and say off value is 1 then this will set brightness to 64 but that is not what the LED framework will send.
> if you read the brightness.
> 
> Is it safe to assume that off_value would always be 0?

No it's not always 0.

In my target application (a microcontroller based LED controller from
Ubiquiti) I have the values from 0 to 63. But after some discussion I
wrote the driver to be more generic so it can cover some similar
controllers too.

So if there is a hypothetical SPI-based controller that uses a single
byte with values from 0x80 (off) to 0x8f (maximum brightness) to control
a LED, you could set the off and max values to these two and the driver
sends 0x80 if you set brightness to 0 and 0x8f if you set brightness to 15.

A more concrete application could be to let the LED slightly on to show
power by setting the off value to for example 10 but letting the max
value at 63. In that case there would be only 53 brightness levels left.

Of course it would have been possible to make it a lot more universal by
for example adding a prefix, a bit mask or other word lengths. But that
would have added a lot of complexity without any actual application.

> 
> 
>> +	mutex_lock(&led->mutex);
>> +	ret = spi_write(led->spi, &value, sizeof(value));
>> +	mutex_unlock(&led->mutex);
>> +
>> +	return ret;
>> +}
>> +
>> +static int spi_byte_probe(struct spi_device *spi)
>> +{
>> +	struct device *dev = &spi->dev;
>> +	struct device_node *child;
>> +	struct spi_byte_led *led;
>> +	int ret;
>> +	const char *default_name = "leds-spi-byte::";
>> +	const char *name;
>> +	u8 off_value;
>> +	u8 max_value;
>> +
>> +	if (!dev->of_node)
>> +		return -ENODEV;
>> +
>> +	if (of_get_child_count(dev->of_node) != 1) {
>> +		dev_err(dev, "Device must have exactly one LED sub-node.");
>> +		return -EINVAL;
>> +	}
>> +	child = of_get_next_child(dev->of_node, NULL);
>> +
>> +	ret = of_property_read_string(child, "label", &name);
>> +	if (ret)
>> +		name = default_name;
>> +
>> +	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value);
>> +	if (ret) {
>> +		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>> +		return -EINVAL;
>> +	}
>> +
>> +	ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value);
>> +	if (ret) {
>> +		dev_err(dev, "LED node needs a leds-spi-byte,max-value.");
>> +		return -EINVAL;
>> +	}
>> +
> 
> You could probably allocate the led struct memory first and then pass in the address of those
> variables as opposed to creating the stack variables.
> 
> 	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
> 	if (!led)
> 		return -ENOMEM;
> 
> 	ret = of_property_read_string(child, "label", &led->ldev.name);
> 	if (ret)
> 		led->ldev.name = default_name;
> 
> 	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &led->off_value);
> 	if (ret) {
> 		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
> 		return -EINVAL;
> 	}
> 	.
> 	.
> 	.

I had that in the first revision. Also no one objected, I noted that I
had to search whether I have initialized all fields when I added another
one. Therefore I thought it would be more readable if I initialize the
complete structure at one location. I put readability over efficiency in
that case because it's only called once during initialization. Of course
I can change that back.

> 
> 
>> +	if (off_value >= max_value) {
>> +		dev_err(dev, "off-value has to be smaller than max-value.");
>> +		return -EINVAL;
>> +	}
>> +
>> +	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>> +	if (!led)
>> +		return -ENOMEM;
>> +
>> +	led->spi = spi;
>> +	strlcpy(led->name, name, sizeof(led->name));
>> +	mutex_init(&led->mutex);
>> +	led->off_value = off_value;
>> +	led->max_value = max_value;
>> +	led->ldev.name = led->name;
>> +	led->ldev.max_brightness = led->max_value - led->off_value;
> 
> Again not sure why this is needed.  This is changing the behavior of what max brightness value is defined in the DT.
> And this is not documented in the DT doc.
> 
> max_value = 255 off_value = 254 meets all the criteria but then LED framework has max brightness is 1
> But that is not what is described in the DT.

Then my description in the DT wasn't clear enough. I wanted to express
that with the sentence: "The value of the byte can be any value between
the off-value and max-value defined in the properties."

Should I add another example (beneath the Ubiquiti controller) like the
following in the description to make it more clear?

"Another example could be a controller with the following control byte
structure:
- Bit 8 to 5: always 0x8
- Bit 4 to 0: brightness value
In that case the off-value would be 0x80 and the max-value would be 0x8f."

> 
>> +	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
>> +	ret = devm_led_classdev_register(&spi->dev, &led->ldev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	spi_set_drvdata(spi, led);
> 
> If you move this above the registration this can just become
> 
> return = devm_led_classdev_register(&spi->dev, &led->ldev);

Good point. I'll change that.

> 
>> +
>> +	return 0;
>> +}
>> +
>> +static int spi_byte_remove(struct spi_device *spi)
>> +{
>> +	struct spi_byte_led	*led = spi_get_drvdata(spi);
>> +
>> +	led_classdev_unregister(&led->ldev);
> 
> Don't need this with devm call

Thanks for the hint. Jacek told me that already. I wanted to wait for
some further feedback before spamming the list with another version.

> 
> Dan
> 
> <snip>
> 

Best regards

Christian

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 12:59     ` Christian Mauderer
@ 2019-05-06 14:58       ` Dan Murphy
  2019-05-06 15:15         ` Pavel Machek
  2019-05-06 15:19         ` Christian Mauderer
  0 siblings, 2 replies; 28+ messages in thread
From: Dan Murphy @ 2019-05-06 14:58 UTC (permalink / raw)
  To: Christian Mauderer, linux-leds, devicetree, Jacek Anaszewski,
	Pavel Machek
  Cc: Rob Herring, Mark Rutland



On 5/6/19 7:59 AM, Christian Mauderer wrote:
> Hello Dan,
> 
> thanks for reviewing the patch.
> 
> On 06/05/2019 14:05, Dan Murphy wrote:
>> Christian
>>
>> On 5/5/19 3:00 PM, oss@c-mauderer.de wrote:
>>> From: Christian Mauderer <oss@c-mauderer.de>
>>>
>>> This driver adds support for simple SPI based LED controller which use
>>> only one byte for setting the brightness.
>>>
>>> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
>>> ---
>>>
>>> Changes compared to v2:
>>> - use "if (ret)" instead of "if (ret != 0)"
>>> - don't initialize ldev-fields with zero
>>> - use devm_led_classdev_register instead of led_classdev_register
>>> - check for error instead of good case with the last if in spi_byte_probe
>>>
>>> Changes compared to v1:
>>> - rename ubnt-spi to leds-spi-byte
>>> - rework probe to get all parameters before allocating anything -> error checks
>>>   all collected together and initializing all fields of the device structure is
>>>   more obvious
>>> - fix some unsteady indentations during variable declaration
>>> - rework comment with protocol explanation
>>> - handle case of off_bright > max_bright
>>> - fix spelling in commit message
>>> - mutex_destroy in remove
>>> - change label to use either use the given one without a prefix or a default one
>>>
>>>
>>>  drivers/leds/Kconfig         |  12 ++++
>>>  drivers/leds/Makefile        |   1 +
>>>  drivers/leds/leds-spi-byte.c | 134 +++++++++++++++++++++++++++++++++++
>>>  3 files changed, 147 insertions(+)
>>>  create mode 100644 drivers/leds/leds-spi-byte.c
>>>
>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>> index a72f97fca57b..0866c55e8004 100644
>>> --- a/drivers/leds/Kconfig
>>> +++ b/drivers/leds/Kconfig
>>> @@ -766,6 +766,18 @@ config LEDS_NIC78BX
>>>  	  To compile this driver as a module, choose M here: the module
>>>  	  will be called leds-nic78bx.
>>>  
>>> +config LEDS_SPI_BYTE
>>> +	tristate "LED support for SPI LED controller with a single byte"
>>> +	depends on LEDS_CLASS
>>> +	depends on SPI
>>> +	depends on OF
>>> +	help
>>> +	  This option enables support for LED controller which use a single byte
>>> +	  for controlling the brightness. The minimum and maximum value of the
>>> +	  byte can be configured via a device tree. The driver can be used for
>>> +	  example for the microcontroller based LED controller in the Ubiquiti
>>> +	  airCube ISP devices.
>>> +
>>>  comment "LED Triggers"
>>>  source "drivers/leds/trigger/Kconfig"
>>>  
>>> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
>>> index 4c1b0054f379..1786d7e2c236 100644
>>> --- a/drivers/leds/Makefile
>>> +++ b/drivers/leds/Makefile
>>> @@ -75,6 +75,7 @@ obj-$(CONFIG_LEDS_PM8058)		+= leds-pm8058.o
>>>  obj-$(CONFIG_LEDS_MLXCPLD)		+= leds-mlxcpld.o
>>>  obj-$(CONFIG_LEDS_MLXREG)		+= leds-mlxreg.o
>>>  obj-$(CONFIG_LEDS_NIC78BX)		+= leds-nic78bx.o
>>> +obj-$(CONFIG_LEDS_SPI_BYTE)		+= leds-spi-byte.o
>>>  obj-$(CONFIG_LEDS_MT6323)		+= leds-mt6323.o
>>>  obj-$(CONFIG_LEDS_LM3692X)		+= leds-lm3692x.o
>>>  obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
>>> diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c
>>> new file mode 100644
>>> index 000000000000..8170b2da497a
>>> --- /dev/null
>>> +++ b/drivers/leds/leds-spi-byte.c
>>> @@ -0,0 +1,134 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de>
>>> +
>>> +/*
>>> + * The driver can be used for controllers with a very simple SPI protocol: Only
>>> + * one byte between an off and a max value (defined by devicetree) will be sent.
>>> + */
>>> +
>>> +#include <linux/leds.h>
>>> +#include <linux/module.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/spi/spi.h>
>>> +#include <linux/mutex.h>
>>> +#include <uapi/linux/uleds.h>
>>> +
>>> +struct spi_byte_led {
>>> +	struct led_classdev	ldev;
>>> +	struct spi_device	*spi;
>>> +	char			name[LED_MAX_NAME_SIZE];
>>> +	struct mutex		mutex;
>>> +	u8			off_value;
>>> +	u8			max_value;
>>> +};
>>> +
>>> +static int spi_byte_brightness_set_blocking(struct led_classdev *dev,
>>> +					    enum led_brightness brightness)
>>> +{
>>> +	struct spi_byte_led *led = container_of(dev, struct spi_byte_led, ldev);
>>> +	u8 value;
>>> +	int ret;
>>> +
>>> +	value = (u8) brightness + led->off_value;
>>> +
>>
>> Sorry if this has been addressed but the versions moved fast.
>>
>> What is the purpose of adding the off_value?
>>
>> If max is 63 and say off value is 1 then this will set brightness to 64 but that is not what the LED framework will send.
>> if you read the brightness.
>>
>> Is it safe to assume that off_value would always be 0?
> 
> No it's not always 0.
> 
> In my target application (a microcontroller based LED controller from
> Ubiquiti) I have the values from 0 to 63. But after some discussion I
> wrote the driver to be more generic so it can cover some similar
> controllers too.
> 
> So if there is a hypothetical SPI-based controller that uses a single
> byte with values from 0x80 (off) to 0x8f (maximum brightness) to control
> a LED, you could set the off and max values to these two and the driver
> sends 0x80 if you set brightness to 0 and 0x8f if you set brightness to 15.
> 

In this case would the max brightness just be 0x7f.
Maybe an optional DT property for brightness mask would help here.

Not sure what the msb is in the example but if this bit defines the  LED on/off control then 
maybe an optional dt property for this would be more clear.

> A more concrete application could be to let the LED slightly on to show
> power by setting the off value to for example 10 but letting the max
> value at 63. In that case there would be only 53 brightness levels left.
> 

But then the LED is not off by user space request.  When the LED is asked to be off
it should be off.  The brightness values requested by the user space should be honored and
not modified by the driver.

> Of course it would have been possible to make it a lot more universal by
> for example adding a prefix, a bit mask or other word lengths. But that
> would have added a lot of complexity without any actual application.
> 

I have to disagree here.  If this is supposed to be a universal SPI byte driver that
needs special handling then it is either needs to be created in a universal way or needs to be made
target specific.

>>
>>
>>> +	mutex_lock(&led->mutex);
>>> +	ret = spi_write(led->spi, &value, sizeof(value));
>>> +	mutex_unlock(&led->mutex);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static int spi_byte_probe(struct spi_device *spi)
>>> +{
>>> +	struct device *dev = &spi->dev;
>>> +	struct device_node *child;
>>> +	struct spi_byte_led *led;
>>> +	int ret;
>>> +	const char *default_name = "leds-spi-byte::";
>>> +	const char *name;
>>> +	u8 off_value;
>>> +	u8 max_value;
>>> +
>>> +	if (!dev->of_node)
>>> +		return -ENODEV;
>>> +
>>> +	if (of_get_child_count(dev->of_node) != 1) {
>>> +		dev_err(dev, "Device must have exactly one LED sub-node.");
>>> +		return -EINVAL;
>>> +	}
>>> +	child = of_get_next_child(dev->of_node, NULL);
>>> +
>>> +	ret = of_property_read_string(child, "label", &name);
>>> +	if (ret)
>>> +		name = default_name;
>>> +
>>> +	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value);
>>> +	if (ret) {
>>> +		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value);
>>> +	if (ret) {
>>> +		dev_err(dev, "LED node needs a leds-spi-byte,max-value.");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>
>> You could probably allocate the led struct memory first and then pass in the address of those
>> variables as opposed to creating the stack variables.
>>
>> 	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>> 	if (!led)
>> 		return -ENOMEM;
>>
>> 	ret = of_property_read_string(child, "label", &led->ldev.name);
>> 	if (ret)
>> 		led->ldev.name = default_name;
>>
>> 	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &led->off_value);
>> 	if (ret) {
>> 		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>> 		return -EINVAL;
>> 	}
>> 	.
>> 	.
>> 	.
> 
> I had that in the first revision. Also no one objected, I noted that I
> had to search whether I have initialized all fields when I added another
> one. Therefore I thought it would be more readable if I initialize the
> complete structure at one location. I put readability over efficiency in
> that case because it's only called once during initialization. Of course
> I can change that back.
> 

Well for readability you could also create a function that parses the node after allocating
the memory.  That way all the DT parsing and value checking is done in a single function.

>>
>>
>>> +	if (off_value >= max_value) {
>>> +		dev_err(dev, "off-value has to be smaller than max-value.");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>>> +	if (!led)
>>> +		return -ENOMEM;
>>> +
>>> +	led->spi = spi;
>>> +	strlcpy(led->name, name, sizeof(led->name));
>>> +	mutex_init(&led->mutex);
>>> +	led->off_value = off_value;
>>> +	led->max_value = max_value;
>>> +	led->ldev.name = led->name;
>>> +	led->ldev.max_brightness = led->max_value - led->off_value;
>>
>> Again not sure why this is needed.  This is changing the behavior of what max brightness value is defined in the DT.
>> And this is not documented in the DT doc.
>>
>> max_value = 255 off_value = 254 meets all the criteria but then LED framework has max brightness is 1
>> But that is not what is described in the DT.
> 
> Then my description in the DT wasn't clear enough. I wanted to express
> that with the sentence: "The value of the byte can be any value between
> the off-value and max-value defined in the properties."
> 
> Should I add another example (beneath the Ubiquiti controller) like the
> following in the description to make it more clear?
> 
> "Another example could be a controller with the following control byte
> structure:
> - Bit 8 to 5: always 0x8
> - Bit 4 to 0: brightness value
> In that case the off-value would be 0x80 and the max-value would be 0x8f."
> 

In this case max-brightness would be 0xf.  No math needed.  With the aid of a brightness mask
then the code would need to do a read before write.
This makes this driver more extensible if it truly needs to be universal and generic.

read_value = 0

if (led->brightness_mask)
	spi_read()

value = (u8) brightness & led->brightness_mask | read_value; 
// or it can also skip brightness_mask and use max_brightness
// value = (u8) brightness & led->max_brightness | read_value; 

spi_write(value)

This aligns what is declared in the DT to what is expected from the user space.

>>
>>> +	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
>>> +	ret = devm_led_classdev_register(&spi->dev, &led->ldev);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	spi_set_drvdata(spi, led);
>>
>> If you move this above the registration this can just become
>>
>> return = devm_led_classdev_register(&spi->dev, &led->ldev);
> 
> Good point. I'll change that.
> 
>>
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int spi_byte_remove(struct spi_device *spi)
>>> +{
>>> +	struct spi_byte_led	*led = spi_get_drvdata(spi);
>>> +
>>> +	led_classdev_unregister(&led->ldev);
>>
>> Don't need this with devm call
> 
> Thanks for the hint. Jacek told me that already. I wanted to wait for
> some further feedback before spamming the list with another version.
> 

One other thing if the LED driver is removed and the LED is on and unmanaged that is ok?

Dan

>>
>> Dan
>>
>> <snip>
>>
> 
> Best regards
> 
> Christian
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 14:58       ` Dan Murphy
@ 2019-05-06 15:15         ` Pavel Machek
  2019-05-06 15:29           ` Christian Mauderer
  2019-05-06 15:19         ` Christian Mauderer
  1 sibling, 1 reply; 28+ messages in thread
From: Pavel Machek @ 2019-05-06 15:15 UTC (permalink / raw)
  To: Dan Murphy
  Cc: Christian Mauderer, linux-leds, devicetree, Jacek Anaszewski,
	Rob Herring, Mark Rutland

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

Hi!

> > Of course it would have been possible to make it a lot more universal by
> > for example adding a prefix, a bit mask or other word lengths. But that
> > would have added a lot of complexity without any actual application.
> > 
> 
> I have to disagree here.  If this is supposed to be a universal SPI byte driver that
> needs special handling then it is either needs to be created in a universal way or needs to be made
> target specific.
> 

Let him be. The driver is good.

If some hardware needs more flexibility, we add it.

No need to have 1000 releases of everything.

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 14:58       ` Dan Murphy
  2019-05-06 15:15         ` Pavel Machek
@ 2019-05-06 15:19         ` Christian Mauderer
  2019-05-06 15:37           ` Dan Murphy
  1 sibling, 1 reply; 28+ messages in thread
From: Christian Mauderer @ 2019-05-06 15:19 UTC (permalink / raw)
  To: Dan Murphy, linux-leds, devicetree, Jacek Anaszewski,
	Pavel Machek
  Cc: Rob Herring, Mark Rutland

On 06/05/2019 16:58, Dan Murphy wrote:
> 
> 
> On 5/6/19 7:59 AM, Christian Mauderer wrote:
>> Hello Dan,
>>
>> thanks for reviewing the patch.
>>
>> On 06/05/2019 14:05, Dan Murphy wrote:
>>> Christian
>>>
>>> On 5/5/19 3:00 PM, oss@c-mauderer.de wrote:
>>>> From: Christian Mauderer <oss@c-mauderer.de>
>>>>
>>>> This driver adds support for simple SPI based LED controller which use
>>>> only one byte for setting the brightness.
>>>>
>>>> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
>>>> ---
>>>>
>>>> Changes compared to v2:
>>>> - use "if (ret)" instead of "if (ret != 0)"
>>>> - don't initialize ldev-fields with zero
>>>> - use devm_led_classdev_register instead of led_classdev_register
>>>> - check for error instead of good case with the last if in spi_byte_probe
>>>>
>>>> Changes compared to v1:
>>>> - rename ubnt-spi to leds-spi-byte
>>>> - rework probe to get all parameters before allocating anything -> error checks
>>>>   all collected together and initializing all fields of the device structure is
>>>>   more obvious
>>>> - fix some unsteady indentations during variable declaration
>>>> - rework comment with protocol explanation
>>>> - handle case of off_bright > max_bright
>>>> - fix spelling in commit message
>>>> - mutex_destroy in remove
>>>> - change label to use either use the given one without a prefix or a default one
>>>>
>>>>
>>>>  drivers/leds/Kconfig         |  12 ++++
>>>>  drivers/leds/Makefile        |   1 +
>>>>  drivers/leds/leds-spi-byte.c | 134 +++++++++++++++++++++++++++++++++++
>>>>  3 files changed, 147 insertions(+)
>>>>  create mode 100644 drivers/leds/leds-spi-byte.c
>>>>
>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>> index a72f97fca57b..0866c55e8004 100644
>>>> --- a/drivers/leds/Kconfig
>>>> +++ b/drivers/leds/Kconfig
>>>> @@ -766,6 +766,18 @@ config LEDS_NIC78BX
>>>>  	  To compile this driver as a module, choose M here: the module
>>>>  	  will be called leds-nic78bx.
>>>>  
>>>> +config LEDS_SPI_BYTE
>>>> +	tristate "LED support for SPI LED controller with a single byte"
>>>> +	depends on LEDS_CLASS
>>>> +	depends on SPI
>>>> +	depends on OF
>>>> +	help
>>>> +	  This option enables support for LED controller which use a single byte
>>>> +	  for controlling the brightness. The minimum and maximum value of the
>>>> +	  byte can be configured via a device tree. The driver can be used for
>>>> +	  example for the microcontroller based LED controller in the Ubiquiti
>>>> +	  airCube ISP devices.
>>>> +
>>>>  comment "LED Triggers"
>>>>  source "drivers/leds/trigger/Kconfig"
>>>>  
>>>> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
>>>> index 4c1b0054f379..1786d7e2c236 100644
>>>> --- a/drivers/leds/Makefile
>>>> +++ b/drivers/leds/Makefile
>>>> @@ -75,6 +75,7 @@ obj-$(CONFIG_LEDS_PM8058)		+= leds-pm8058.o
>>>>  obj-$(CONFIG_LEDS_MLXCPLD)		+= leds-mlxcpld.o
>>>>  obj-$(CONFIG_LEDS_MLXREG)		+= leds-mlxreg.o
>>>>  obj-$(CONFIG_LEDS_NIC78BX)		+= leds-nic78bx.o
>>>> +obj-$(CONFIG_LEDS_SPI_BYTE)		+= leds-spi-byte.o
>>>>  obj-$(CONFIG_LEDS_MT6323)		+= leds-mt6323.o
>>>>  obj-$(CONFIG_LEDS_LM3692X)		+= leds-lm3692x.o
>>>>  obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
>>>> diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c
>>>> new file mode 100644
>>>> index 000000000000..8170b2da497a
>>>> --- /dev/null
>>>> +++ b/drivers/leds/leds-spi-byte.c
>>>> @@ -0,0 +1,134 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>> +// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de>
>>>> +
>>>> +/*
>>>> + * The driver can be used for controllers with a very simple SPI protocol: Only
>>>> + * one byte between an off and a max value (defined by devicetree) will be sent.
>>>> + */
>>>> +
>>>> +#include <linux/leds.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/of_device.h>
>>>> +#include <linux/spi/spi.h>
>>>> +#include <linux/mutex.h>
>>>> +#include <uapi/linux/uleds.h>
>>>> +
>>>> +struct spi_byte_led {
>>>> +	struct led_classdev	ldev;
>>>> +	struct spi_device	*spi;
>>>> +	char			name[LED_MAX_NAME_SIZE];
>>>> +	struct mutex		mutex;
>>>> +	u8			off_value;
>>>> +	u8			max_value;
>>>> +};
>>>> +
>>>> +static int spi_byte_brightness_set_blocking(struct led_classdev *dev,
>>>> +					    enum led_brightness brightness)
>>>> +{
>>>> +	struct spi_byte_led *led = container_of(dev, struct spi_byte_led, ldev);
>>>> +	u8 value;
>>>> +	int ret;
>>>> +
>>>> +	value = (u8) brightness + led->off_value;
>>>> +
>>>
>>> Sorry if this has been addressed but the versions moved fast.
>>>
>>> What is the purpose of adding the off_value?
>>>
>>> If max is 63 and say off value is 1 then this will set brightness to 64 but that is not what the LED framework will send.
>>> if you read the brightness.
>>>
>>> Is it safe to assume that off_value would always be 0?
>>
>> No it's not always 0.
>>
>> In my target application (a microcontroller based LED controller from
>> Ubiquiti) I have the values from 0 to 63. But after some discussion I
>> wrote the driver to be more generic so it can cover some similar
>> controllers too.
>>
>> So if there is a hypothetical SPI-based controller that uses a single
>> byte with values from 0x80 (off) to 0x8f (maximum brightness) to control
>> a LED, you could set the off and max values to these two and the driver
>> sends 0x80 if you set brightness to 0 and 0x8f if you set brightness to 15.
>>
> 
> In this case would the max brightness just be 0x7f.
> Maybe an optional DT property for brightness mask would help here.
> 
> Not sure what the msb is in the example but if this bit defines the  LED on/off control then 
> maybe an optional dt property for this would be more clear.
> 
>> A more concrete application could be to let the LED slightly on to show
>> power by setting the off value to for example 10 but letting the max
>> value at 63. In that case there would be only 53 brightness levels left.
>>
> 
> But then the LED is not off by user space request.  When the LED is asked to be off
> it should be off.  The brightness values requested by the user space should be honored and
> not modified by the driver.

That's correct. It was an example what would be possible. You are
correct that this would be an ugly hack.

> 
>> Of course it would have been possible to make it a lot more universal by
>> for example adding a prefix, a bit mask or other word lengths. But that
>> would have added a lot of complexity without any actual application.
>>
> 
> I have to disagree here.  If this is supposed to be a universal SPI byte driver that
> needs special handling then it is either needs to be created in a universal way or needs to be made
> target specific.

If it should be a truly universal driver for SPI based controllers I
would at least need the following additional features:

- Variable direction (led brighter with lower or higher values).
- Counter at any location of the byte. Maybe even some odd combinations
like bit 7, 3 and 5 in this order.
- Sending some bytes before the LED brightness value.
- Sending multiple bytes for multiple LEDs.
- Configurable other bits.

And that would only include controllers without a SPI MISO channel. So
where does "universal" stop? I stopped when my application and maybe
some others (like using a digital potentiometer with an similar
interface) could be covered.

So it's not a universal but a multi-purpose driver that can be used for
every controller with the following interface:

- Only has a MOSI line. MISO can be ignored.
- Expect one byte via SPI.
- Expect a range of values from x to y to set brightness from off (x) to
bright (y).

It can be extended if an application appears that needs more than that.
Maybe it's a good idea to add that list of requirements to the device
tree description?

> 
>>>
>>>
>>>> +	mutex_lock(&led->mutex);
>>>> +	ret = spi_write(led->spi, &value, sizeof(value));
>>>> +	mutex_unlock(&led->mutex);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +static int spi_byte_probe(struct spi_device *spi)
>>>> +{
>>>> +	struct device *dev = &spi->dev;
>>>> +	struct device_node *child;
>>>> +	struct spi_byte_led *led;
>>>> +	int ret;
>>>> +	const char *default_name = "leds-spi-byte::";
>>>> +	const char *name;
>>>> +	u8 off_value;
>>>> +	u8 max_value;
>>>> +
>>>> +	if (!dev->of_node)
>>>> +		return -ENODEV;
>>>> +
>>>> +	if (of_get_child_count(dev->of_node) != 1) {
>>>> +		dev_err(dev, "Device must have exactly one LED sub-node.");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +	child = of_get_next_child(dev->of_node, NULL);
>>>> +
>>>> +	ret = of_property_read_string(child, "label", &name);
>>>> +	if (ret)
>>>> +		name = default_name;
>>>> +
>>>> +	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value);
>>>> +	if (ret) {
>>>> +		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value);
>>>> +	if (ret) {
>>>> +		dev_err(dev, "LED node needs a leds-spi-byte,max-value.");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>
>>> You could probably allocate the led struct memory first and then pass in the address of those
>>> variables as opposed to creating the stack variables.
>>>
>>> 	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>>> 	if (!led)
>>> 		return -ENOMEM;
>>>
>>> 	ret = of_property_read_string(child, "label", &led->ldev.name);
>>> 	if (ret)
>>> 		led->ldev.name = default_name;
>>>
>>> 	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &led->off_value);
>>> 	if (ret) {
>>> 		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>>> 		return -EINVAL;
>>> 	}
>>> 	.
>>> 	.
>>> 	.
>>
>> I had that in the first revision. Also no one objected, I noted that I
>> had to search whether I have initialized all fields when I added another
>> one. Therefore I thought it would be more readable if I initialize the
>> complete structure at one location. I put readability over efficiency in
>> that case because it's only called once during initialization. Of course
>> I can change that back.
>>
> 
> Well for readability you could also create a function that parses the node after allocating
> the memory.  That way all the DT parsing and value checking is done in a single function.
> 

OK for me too. I'm quite indifferent here. It's a matter of preference
how to style something like that.

>>>
>>>
>>>> +	if (off_value >= max_value) {
>>>> +		dev_err(dev, "off-value has to be smaller than max-value.");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>>>> +	if (!led)
>>>> +		return -ENOMEM;
>>>> +
>>>> +	led->spi = spi;
>>>> +	strlcpy(led->name, name, sizeof(led->name));
>>>> +	mutex_init(&led->mutex);
>>>> +	led->off_value = off_value;
>>>> +	led->max_value = max_value;
>>>> +	led->ldev.name = led->name;
>>>> +	led->ldev.max_brightness = led->max_value - led->off_value;
>>>
>>> Again not sure why this is needed.  This is changing the behavior of what max brightness value is defined in the DT.
>>> And this is not documented in the DT doc.
>>>
>>> max_value = 255 off_value = 254 meets all the criteria but then LED framework has max brightness is 1
>>> But that is not what is described in the DT.
>>
>> Then my description in the DT wasn't clear enough. I wanted to express
>> that with the sentence: "The value of the byte can be any value between
>> the off-value and max-value defined in the properties."
>>
>> Should I add another example (beneath the Ubiquiti controller) like the
>> following in the description to make it more clear?
>>
>> "Another example could be a controller with the following control byte
>> structure:
>> - Bit 8 to 5: always 0x8
>> - Bit 4 to 0: brightness value
>> In that case the off-value would be 0x80 and the max-value would be 0x8f."
>>
> 
> In this case max-brightness would be 0xf.  No math needed.  With the aid of a brightness mask
> then the code would need to do a read before write.
> This makes this driver more extensible if it truly needs to be universal and generic.

That would mean that the controller allows a read of the register. Not
every controller does that. For example the one I want to support just
returns the previously sent byte.

> 
> read_value = 0
> 
> if (led->brightness_mask)
> 	spi_read()
> 
> value = (u8) brightness & led->brightness_mask | read_value; 
> // or it can also skip brightness_mask and use max_brightness
> // value = (u8) brightness & led->max_brightness | read_value; 
> 
> spi_write(value)
> 
> This aligns what is declared in the DT to what is expected from the user space.
> >>>
>>>> +	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
>>>> +	ret = devm_led_classdev_register(&spi->dev, &led->ldev);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	spi_set_drvdata(spi, led);
>>>
>>> If you move this above the registration this can just become
>>>
>>> return = devm_led_classdev_register(&spi->dev, &led->ldev);
>>
>> Good point. I'll change that.
>>
>>>
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int spi_byte_remove(struct spi_device *spi)
>>>> +{
>>>> +	struct spi_byte_led	*led = spi_get_drvdata(spi);
>>>> +
>>>> +	led_classdev_unregister(&led->ldev);
>>>
>>> Don't need this with devm call
>>
>> Thanks for the hint. Jacek told me that already. I wanted to wait for
>> some further feedback before spamming the list with another version.
>>
> 
> One other thing if the LED driver is removed and the LED is on and unmanaged that is ok?
> 

Is that any different for any of the other drivers? As soon as I remove
a driver, the device is unmanaged, isn't it?

Best regards

Christian

> Dan
> 
>>>
>>> Dan
>>>
>>> <snip>
>>>
>>
>> Best regards
>>
>> Christian
>>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 15:15         ` Pavel Machek
@ 2019-05-06 15:29           ` Christian Mauderer
  2019-05-06 17:40             ` Dan Murphy
  0 siblings, 1 reply; 28+ messages in thread
From: Christian Mauderer @ 2019-05-06 15:29 UTC (permalink / raw)
  To: Pavel Machek, Dan Murphy
  Cc: linux-leds, devicetree, Jacek Anaszewski, Rob Herring,
	Mark Rutland

On 06/05/2019 17:15, Pavel Machek wrote:
> Hi!
> 
>>> Of course it would have been possible to make it a lot more universal by
>>> for example adding a prefix, a bit mask or other word lengths. But that
>>> would have added a lot of complexity without any actual application.
>>>
>>
>> I have to disagree here.  If this is supposed to be a universal SPI byte driver that
>> needs special handling then it is either needs to be created in a universal way or needs to be made
>> target specific.
>>
> 
> Let him be. The driver is good.
> 
> If some hardware needs more flexibility, we add it.
> 
> No need to have 1000 releases of everything.
> 
> 									Pavel
> 

Hello Pavel,

thanks for the support.

It's a pure hobby project so I have the time to add useful features or
to improve the description to make it clear what the drivers intention
is. So if we find a more useful set of features it's a good idea to
discuss it.

By the way: Although I haven't written a Linux driver yet it's not my
first open source project. So I know that there can be a lot of
different opinions and sometimes a lot of revisions. So no big risk of
scaring me away.

Best regards

Christian

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 15:19         ` Christian Mauderer
@ 2019-05-06 15:37           ` Dan Murphy
  2019-05-06 15:42             ` Christian Mauderer
  0 siblings, 1 reply; 28+ messages in thread
From: Dan Murphy @ 2019-05-06 15:37 UTC (permalink / raw)
  To: Christian Mauderer, linux-leds, devicetree, Jacek Anaszewski,
	Pavel Machek
  Cc: Rob Herring, Mark Rutland

Christian

On 5/6/19 10:19 AM, Christian Mauderer wrote:
> On 06/05/2019 16:58, Dan Murphy wrote:
<snip>

> 
> If it should be a truly universal driver for SPI based controllers I
> would at least need the following additional features:
> 
> - Variable direction (led brighter with lower or higher values).
> - Counter at any location of the byte. Maybe even some odd combinations
> like bit 7, 3 and 5 in this order.
> - Sending some bytes before the LED brightness value.
> - Sending multiple bytes for multiple LEDs.
> - Configurable other bits.
> 
> And that would only include controllers without a SPI MISO channel. So
> where does "universal" stop? I stopped when my application and maybe
> some others (like using a digital potentiometer with an similar
> interface) could be covered.
> 
> So it's not a universal but a multi-purpose driver that can be used for
> every controller with the following interface:
> 
> - Only has a MOSI line. MISO can be ignored.
> - Expect one byte via SPI.
> - Expect a range of values from x to y to set brightness from off (x) to
> bright (y).
> 
> It can be extended if an application appears that needs more than that.
> Maybe it's a good idea to add that list of requirements to the device
> tree description?
> 

Yes that would be a good idea since it is a multi-purpose driver with very specific requirements.

>>
>>>>
>>>>
>>>>> +	mutex_lock(&led->mutex);
>>>>> +	ret = spi_write(led->spi, &value, sizeof(value));
>>>>> +	mutex_unlock(&led->mutex);
>>>>> +
>>>>> +	return ret;
>>>>> +}
>>>>> +
>>>>> +static int spi_byte_probe(struct spi_device *spi)
>>>>> +{
>>>>> +	struct device *dev = &spi->dev;
>>>>> +	struct device_node *child;
>>>>> +	struct spi_byte_led *led;
>>>>> +	int ret;
>>>>> +	const char *default_name = "leds-spi-byte::";
>>>>> +	const char *name;
>>>>> +	u8 off_value;
>>>>> +	u8 max_value;
>>>>> +
>>>>> +	if (!dev->of_node)
>>>>> +		return -ENODEV;
>>>>> +
>>>>> +	if (of_get_child_count(dev->of_node) != 1) {
>>>>> +		dev_err(dev, "Device must have exactly one LED sub-node.");
>>>>> +		return -EINVAL;
>>>>> +	}
>>>>> +	child = of_get_next_child(dev->of_node, NULL);
>>>>> +
>>>>> +	ret = of_property_read_string(child, "label", &name);
>>>>> +	if (ret)
>>>>> +		name = default_name;
>>>>> +
>>>>> +	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value);
>>>>> +	if (ret) {
>>>>> +		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>>>>> +		return -EINVAL;
>>>>> +	}
>>>>> +
>>>>> +	ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value);
>>>>> +	if (ret) {
>>>>> +		dev_err(dev, "LED node needs a leds-spi-byte,max-value.");
>>>>> +		return -EINVAL;
>>>>> +	}
>>>>> +
>>>>
>>>> You could probably allocate the led struct memory first and then pass in the address of those
>>>> variables as opposed to creating the stack variables.
>>>>
>>>> 	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>>>> 	if (!led)
>>>> 		return -ENOMEM;
>>>>
>>>> 	ret = of_property_read_string(child, "label", &led->ldev.name);
>>>> 	if (ret)
>>>> 		led->ldev.name = default_name;
>>>>
>>>> 	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &led->off_value);
>>>> 	if (ret) {
>>>> 		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>>>> 		return -EINVAL;
>>>> 	}
>>>> 	.
>>>> 	.
>>>> 	.
>>>
>>> I had that in the first revision. Also no one objected, I noted that I
>>> had to search whether I have initialized all fields when I added another
>>> one. Therefore I thought it would be more readable if I initialize the
>>> complete structure at one location. I put readability over efficiency in
>>> that case because it's only called once during initialization. Of course
>>> I can change that back.
>>>
>>
>> Well for readability you could also create a function that parses the node after allocating
>> the memory.  That way all the DT parsing and value checking is done in a single function.
>>
> 
> OK for me too. I'm quite indifferent here. It's a matter of preference
> how to style something like that.
> 

True not saying to do create the function it was just a suggestion.

>>>>
>>>>
>>>>> +	if (off_value >= max_value) {
>>>>> +		dev_err(dev, "off-value has to be smaller than max-value.");
>>>>> +		return -EINVAL;
>>>>> +	}
>>>>> +
>>>>> +	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>>>>> +	if (!led)
>>>>> +		return -ENOMEM;
>>>>> +
>>>>> +	led->spi = spi;
>>>>> +	strlcpy(led->name, name, sizeof(led->name));
>>>>> +	mutex_init(&led->mutex);
>>>>> +	led->off_value = off_value;
>>>>> +	led->max_value = max_value;
>>>>> +	led->ldev.name = led->name;
>>>>> +	led->ldev.max_brightness = led->max_value - led->off_value;
>>>>
>>>> Again not sure why this is needed.  This is changing the behavior of what max brightness value is defined in the DT.
>>>> And this is not documented in the DT doc.
>>>>
>>>> max_value = 255 off_value = 254 meets all the criteria but then LED framework has max brightness is 1
>>>> But that is not what is described in the DT.
>>>
>>> Then my description in the DT wasn't clear enough. I wanted to express
>>> that with the sentence: "The value of the byte can be any value between
>>> the off-value and max-value defined in the properties."
>>>
>>> Should I add another example (beneath the Ubiquiti controller) like the
>>> following in the description to make it more clear?
>>>
>>> "Another example could be a controller with the following control byte
>>> structure:
>>> - Bit 8 to 5: always 0x8
>>> - Bit 4 to 0: brightness value
>>> In that case the off-value would be 0x80 and the max-value would be 0x8f."
>>>
>>
>> In this case max-brightness would be 0xf.  No math needed.  With the aid of a brightness mask
>> then the code would need to do a read before write.
>> This makes this driver more extensible if it truly needs to be universal and generic.
> 
> That would mean that the controller allows a read of the register. Not
> every controller does that. For example the one I want to support just
> returns the previously sent byte.
> 

True a spi_read would be ineffective here.

>>
>> read_value = 0
>>
>> if (led->brightness_mask)
>> 	spi_read()
>>
>> value = (u8) brightness & led->brightness_mask | read_value; 
>> // or it can also skip brightness_mask and use max_brightness
>> // value = (u8) brightness & led->max_brightness | read_value; 
>>
>> spi_write(value)
>>
>> This aligns what is declared in the DT to what is expected from the user space.
>>>>>
>>>>> +	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
>>>>> +	ret = devm_led_classdev_register(&spi->dev, &led->ldev);
>>>>> +	if (ret)
>>>>> +		return ret;
>>>>> +
>>>>> +	spi_set_drvdata(spi, led);
>>>>
>>>> If you move this above the registration this can just become
>>>>
>>>> return = devm_led_classdev_register(&spi->dev, &led->ldev);
>>>
>>> Good point. I'll change that.
>>>
>>>>
>>>>> +
>>>>> +	return 0;
>>>>> +}
>>>>> +
>>>>> +static int spi_byte_remove(struct spi_device *spi)
>>>>> +{
>>>>> +	struct spi_byte_led	*led = spi_get_drvdata(spi);
>>>>> +
>>>>> +	led_classdev_unregister(&led->ldev);
>>>>
>>>> Don't need this with devm call
>>>
>>> Thanks for the hint. Jacek told me that already. I wanted to wait for
>>> some further feedback before spamming the list with another version.
>>>
>>
>> One other thing if the LED driver is removed and the LED is on and unmanaged that is ok?
>>
> 
> Is that any different for any of the other drivers? As soon as I remove
> a driver, the device is unmanaged, isn't it?
> 

True.

Dan

> Best regards
> 
> Christian
> 
>> Dan
>>
>>>>
>>>> Dan
>>>>
>>>> <snip>
>>>>
>>>
>>> Best regards
>>>
>>> Christian
>>>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 15:37           ` Dan Murphy
@ 2019-05-06 15:42             ` Christian Mauderer
  0 siblings, 0 replies; 28+ messages in thread
From: Christian Mauderer @ 2019-05-06 15:42 UTC (permalink / raw)
  To: Dan Murphy, linux-leds, devicetree, Jacek Anaszewski,
	Pavel Machek
  Cc: Rob Herring, Mark Rutland

Hello Dan,

On 06/05/2019 17:37, Dan Murphy wrote:
> Christian
> 
> On 5/6/19 10:19 AM, Christian Mauderer wrote:
>> On 06/05/2019 16:58, Dan Murphy wrote:
> <snip>
> 
>>
>> If it should be a truly universal driver for SPI based controllers I
>> would at least need the following additional features:
>>
>> - Variable direction (led brighter with lower or higher values).
>> - Counter at any location of the byte. Maybe even some odd combinations
>> like bit 7, 3 and 5 in this order.
>> - Sending some bytes before the LED brightness value.
>> - Sending multiple bytes for multiple LEDs.
>> - Configurable other bits.
>>
>> And that would only include controllers without a SPI MISO channel. So
>> where does "universal" stop? I stopped when my application and maybe
>> some others (like using a digital potentiometer with an similar
>> interface) could be covered.
>>
>> So it's not a universal but a multi-purpose driver that can be used for
>> every controller with the following interface:
>>
>> - Only has a MOSI line. MISO can be ignored.
>> - Expect one byte via SPI.
>> - Expect a range of values from x to y to set brightness from off (x) to
>> bright (y).
>>
>> It can be extended if an application appears that needs more than that.
>> Maybe it's a good idea to add that list of requirements to the device
>> tree description?
>>
> 
> Yes that would be a good idea since it is a multi-purpose driver with very specific requirements.

OK. I'll improve the description with this list (maybe with a slightly
better formulation).

> 
>>>
>>>>>
>>>>>
>>>>>> +	mutex_lock(&led->mutex);
>>>>>> +	ret = spi_write(led->spi, &value, sizeof(value));
>>>>>> +	mutex_unlock(&led->mutex);
>>>>>> +
>>>>>> +	return ret;
>>>>>> +}
>>>>>> +
>>>>>> +static int spi_byte_probe(struct spi_device *spi)
>>>>>> +{
>>>>>> +	struct device *dev = &spi->dev;
>>>>>> +	struct device_node *child;
>>>>>> +	struct spi_byte_led *led;
>>>>>> +	int ret;
>>>>>> +	const char *default_name = "leds-spi-byte::";
>>>>>> +	const char *name;
>>>>>> +	u8 off_value;
>>>>>> +	u8 max_value;
>>>>>> +
>>>>>> +	if (!dev->of_node)
>>>>>> +		return -ENODEV;
>>>>>> +
>>>>>> +	if (of_get_child_count(dev->of_node) != 1) {
>>>>>> +		dev_err(dev, "Device must have exactly one LED sub-node.");
>>>>>> +		return -EINVAL;
>>>>>> +	}
>>>>>> +	child = of_get_next_child(dev->of_node, NULL);
>>>>>> +
>>>>>> +	ret = of_property_read_string(child, "label", &name);
>>>>>> +	if (ret)
>>>>>> +		name = default_name;
>>>>>> +
>>>>>> +	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value);
>>>>>> +	if (ret) {
>>>>>> +		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>>>>>> +		return -EINVAL;
>>>>>> +	}
>>>>>> +
>>>>>> +	ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value);
>>>>>> +	if (ret) {
>>>>>> +		dev_err(dev, "LED node needs a leds-spi-byte,max-value.");
>>>>>> +		return -EINVAL;
>>>>>> +	}
>>>>>> +
>>>>>
>>>>> You could probably allocate the led struct memory first and then pass in the address of those
>>>>> variables as opposed to creating the stack variables.
>>>>>
>>>>> 	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>>>>> 	if (!led)
>>>>> 		return -ENOMEM;
>>>>>
>>>>> 	ret = of_property_read_string(child, "label", &led->ldev.name);
>>>>> 	if (ret)
>>>>> 		led->ldev.name = default_name;
>>>>>
>>>>> 	ret = of_property_read_u8(child, "leds-spi-byte,off-value", &led->off_value);
>>>>> 	if (ret) {
>>>>> 		dev_err(dev, "LED node needs a leds-spi-byte,off-value.");
>>>>> 		return -EINVAL;
>>>>> 	}
>>>>> 	.
>>>>> 	.
>>>>> 	.
>>>>
>>>> I had that in the first revision. Also no one objected, I noted that I
>>>> had to search whether I have initialized all fields when I added another
>>>> one. Therefore I thought it would be more readable if I initialize the
>>>> complete structure at one location. I put readability over efficiency in
>>>> that case because it's only called once during initialization. Of course
>>>> I can change that back.
>>>>
>>>
>>> Well for readability you could also create a function that parses the node after allocating
>>> the memory.  That way all the DT parsing and value checking is done in a single function.
>>>
>>
>> OK for me too. I'm quite indifferent here. It's a matter of preference
>> how to style something like that.
>>
> 
> True not saying to do create the function it was just a suggestion.
> 

I'll try it and have a look at what is better. If everything open
firmware related is in a extra function, that can simplify a potential
future change to get the information from somewhere else.

>>>>>
>>>>>
>>>>>> +	if (off_value >= max_value) {
>>>>>> +		dev_err(dev, "off-value has to be smaller than max-value.");
>>>>>> +		return -EINVAL;
>>>>>> +	}
>>>>>> +
>>>>>> +	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
>>>>>> +	if (!led)
>>>>>> +		return -ENOMEM;
>>>>>> +
>>>>>> +	led->spi = spi;
>>>>>> +	strlcpy(led->name, name, sizeof(led->name));
>>>>>> +	mutex_init(&led->mutex);
>>>>>> +	led->off_value = off_value;
>>>>>> +	led->max_value = max_value;
>>>>>> +	led->ldev.name = led->name;
>>>>>> +	led->ldev.max_brightness = led->max_value - led->off_value;
>>>>>
>>>>> Again not sure why this is needed.  This is changing the behavior of what max brightness value is defined in the DT.
>>>>> And this is not documented in the DT doc.
>>>>>
>>>>> max_value = 255 off_value = 254 meets all the criteria but then LED framework has max brightness is 1
>>>>> But that is not what is described in the DT.
>>>>
>>>> Then my description in the DT wasn't clear enough. I wanted to express
>>>> that with the sentence: "The value of the byte can be any value between
>>>> the off-value and max-value defined in the properties."
>>>>
>>>> Should I add another example (beneath the Ubiquiti controller) like the
>>>> following in the description to make it more clear?
>>>>
>>>> "Another example could be a controller with the following control byte
>>>> structure:
>>>> - Bit 8 to 5: always 0x8
>>>> - Bit 4 to 0: brightness value
>>>> In that case the off-value would be 0x80 and the max-value would be 0x8f."
>>>>
>>>
>>> In this case max-brightness would be 0xf.  No math needed.  With the aid of a brightness mask
>>> then the code would need to do a read before write.
>>> This makes this driver more extensible if it truly needs to be universal and generic.
>>
>> That would mean that the controller allows a read of the register. Not
>> every controller does that. For example the one I want to support just
>> returns the previously sent byte.
>>
> 
> True a spi_read would be ineffective here.
> 
>>>
>>> read_value = 0
>>>
>>> if (led->brightness_mask)
>>> 	spi_read()
>>>
>>> value = (u8) brightness & led->brightness_mask | read_value; 
>>> // or it can also skip brightness_mask and use max_brightness
>>> // value = (u8) brightness & led->max_brightness | read_value; 
>>>
>>> spi_write(value)
>>>
>>> This aligns what is declared in the DT to what is expected from the user space.
>>>>>>
>>>>>> +	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
>>>>>> +	ret = devm_led_classdev_register(&spi->dev, &led->ldev);
>>>>>> +	if (ret)
>>>>>> +		return ret;
>>>>>> +
>>>>>> +	spi_set_drvdata(spi, led);
>>>>>
>>>>> If you move this above the registration this can just become
>>>>>
>>>>> return = devm_led_classdev_register(&spi->dev, &led->ldev);
>>>>
>>>> Good point. I'll change that.
>>>>
>>>>>
>>>>>> +
>>>>>> +	return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static int spi_byte_remove(struct spi_device *spi)
>>>>>> +{
>>>>>> +	struct spi_byte_led	*led = spi_get_drvdata(spi);
>>>>>> +
>>>>>> +	led_classdev_unregister(&led->ldev);
>>>>>
>>>>> Don't need this with devm call
>>>>
>>>> Thanks for the hint. Jacek told me that already. I wanted to wait for
>>>> some further feedback before spamming the list with another version.
>>>>
>>>
>>> One other thing if the LED driver is removed and the LED is on and unmanaged that is ok?
>>>
>>
>> Is that any different for any of the other drivers? As soon as I remove
>> a driver, the device is unmanaged, isn't it?
>>
> 
> True.
> 
> Dan
> 
>> Best regards
>>
>> Christian
>>
>>> Dan
>>>
>>>>>
>>>>> Dan
>>>>>
>>>>> <snip>
>>>>>
>>>>
>>>> Best regards
>>>>
>>>> Christian
>>>>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-05 20:00 [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED oss
  2019-05-05 20:00 ` [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver oss
@ 2019-05-06 16:21 ` Rob Herring
  2019-05-06 16:28   ` Pavel Machek
  2019-05-06 17:03   ` Christian Mauderer
  1 sibling, 2 replies; 28+ messages in thread
From: Rob Herring @ 2019-05-06 16:21 UTC (permalink / raw)
  To: oss
  Cc: Linux LED Subsystem, devicetree, Jacek Anaszewski, Pavel Machek,
	Dan Murphy, Mark Rutland

On Sun, May 5, 2019 at 3:00 PM <oss@c-mauderer.de> wrote:
>
> From: Christian Mauderer <oss@c-mauderer.de>
>
> This patch adds the binding documentation for a simple SPI based LED
> controller which use only one byte for setting the brightness.
>
> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
> ---
>
> Changes compared to v2:
> - None
>
> Changes compared to v1:
> - rename ubnt-spi to leds-spi-byte
> - rename "ubnt-spi,off_bright" and "ubnt-spi,max_bright" to
>   "leds-spi-byte,off-value" and "leds-spi-byte,max-value" and mark them required
> - rename led-controller node to "led-controller"
> - extend description
> - remove SPI controller
> - use "white:status" for the example label
>
>
>  .../bindings/leds/leds-spi-byte.txt           | 47 +++++++++++++++++++
>  1 file changed, 47 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/leds-spi-byte.txt
>
> diff --git a/Documentation/devicetree/bindings/leds/leds-spi-byte.txt b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
> new file mode 100644
> index 000000000000..1dd6ab03a56d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
> @@ -0,0 +1,47 @@
> +* Single Byte SPI LED Device Driver.
> +
> +The driver can be used for controllers with a very simple SPI protocol: Only one
> +byte will be sent. The value of the byte can be any value between the off-value
> +and max-value defined in the properties.
> +
> +One example where the driver can be used is the controller in Ubiquiti airCube
> +ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX
> +8F26E611LA) that has been programmed to control the single LED of the device.

What about power control of the uC?

> +The controller supports four modes depending on the highest two bits in a byte:
> +One setting for brightness, the other three provide different blink patterns.

This part seems in no way generic.

How does one support the blink patterns?

> +With the leds-spi-byte driver a basic support for the brightness mode of that
> +controller can be easily achieved by setting the minimum and maximum to the
> +brightness modes minimum and maximum byte value.
> +
> +Required properties:
> +- compatible:          Should be "leds-spi-byte".

Generally, we don't do "generic" bindings like this. The exceptions
are either we have confidence they really can be generic or they where
created before we knew better. A sample size of 1 doesn't convince me
the former is true.

This comment *only* applies to the binding, not the driver. Specific
bindings can easily be bound to generic drivers.

> +
> +Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
> +apply. In particular, "reg" and "spi-max-frequency" properties must be given.

What's the SPI mode configuration?

> +
> +The driver currently only supports one LED. The properties of the LED are
> +configured in a sub-node in the device node.
> +
> +LED sub-node properties:
> +- label:
> +       see Documentation/devicetree/bindings/leds/common.txt
> +- leds-spi-byte,off-value:
> +       The SPI byte value that should be sent to switch the LED off. Has to be
> +       smaller than max-value. Range: 0 to 254.
> +- leds-spi-byte,max-value:
> +       The SPI byte value that should be sent to set the LED to the maximum
> +       brightness. Has to be bigger than off-value. Range: 1 to 255.

Can't we already express this with brightness-levels and
num-interpolated-steps properties? Some reason those ended up in
pwm-backlight.txt, but really could apply to any LED with level
controls.

Rob

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 16:21 ` [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED Rob Herring
@ 2019-05-06 16:28   ` Pavel Machek
  2019-05-06 17:44     ` Rob Herring
  2019-05-06 17:03   ` Christian Mauderer
  1 sibling, 1 reply; 28+ messages in thread
From: Pavel Machek @ 2019-05-06 16:28 UTC (permalink / raw)
  To: Rob Herring
  Cc: oss, Linux LED Subsystem, devicetree, Jacek Anaszewski,
	Dan Murphy, Mark Rutland

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

Hi!

> > +* Single Byte SPI LED Device Driver.
> > +
> > +The driver can be used for controllers with a very simple SPI protocol: Only one
> > +byte will be sent. The value of the byte can be any value between the off-value
> > +and max-value defined in the properties.
> > +
> > +One example where the driver can be used is the controller in Ubiquiti airCube
> > +ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX
> > +8F26E611LA) that has been programmed to control the single LED of the device.
> 
> What about power control of the uC?
> 
> > +The controller supports four modes depending on the highest two bits in a byte:
> > +One setting for brightness, the other three provide different blink patterns.
> 
> This part seems in no way generic.
> 
> How does one support the blink patterns?
> 
> > +With the leds-spi-byte driver a basic support for the brightness mode of that
> > +controller can be easily achieved by setting the minimum and maximum to the
> > +brightness modes minimum and maximum byte value.
> > +
> > +Required properties:
> > +- compatible:          Should be "leds-spi-byte".
> 
> Generally, we don't do "generic" bindings like this. The exceptions
> are either we have confidence they really can be generic or they where
> created before we knew better. A sample size of 1 doesn't convince me
> the former is true.
> 
> This comment *only* applies to the binding, not the driver. Specific
> bindings can easily be bound to generic drivers.

Ok, I'm afraid I caused this. What should the compatible be, then?

									Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 16:21 ` [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED Rob Herring
  2019-05-06 16:28   ` Pavel Machek
@ 2019-05-06 17:03   ` Christian Mauderer
  2019-05-06 17:59     ` Rob Herring
  2019-05-06 19:06     ` Jacek Anaszewski
  1 sibling, 2 replies; 28+ messages in thread
From: Christian Mauderer @ 2019-05-06 17:03 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linux LED Subsystem, devicetree, Jacek Anaszewski, Pavel Machek,
	Dan Murphy, Mark Rutland

On 06/05/2019 18:21, Rob Herring wrote:
> On Sun, May 5, 2019 at 3:00 PM <oss@c-mauderer.de> wrote:
>>
>> From: Christian Mauderer <oss@c-mauderer.de>
>>
>> This patch adds the binding documentation for a simple SPI based LED
>> controller which use only one byte for setting the brightness.
>>
>> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
>> ---
>>
>> Changes compared to v2:
>> - None
>>
>> Changes compared to v1:
>> - rename ubnt-spi to leds-spi-byte
>> - rename "ubnt-spi,off_bright" and "ubnt-spi,max_bright" to
>>   "leds-spi-byte,off-value" and "leds-spi-byte,max-value" and mark them required
>> - rename led-controller node to "led-controller"
>> - extend description
>> - remove SPI controller
>> - use "white:status" for the example label
>>
>>
>>  .../bindings/leds/leds-spi-byte.txt           | 47 +++++++++++++++++++
>>  1 file changed, 47 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/leds/leds-spi-byte.txt
>>
>> diff --git a/Documentation/devicetree/bindings/leds/leds-spi-byte.txt b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
>> new file mode 100644
>> index 000000000000..1dd6ab03a56d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
>> @@ -0,0 +1,47 @@
>> +* Single Byte SPI LED Device Driver.
>> +
>> +The driver can be used for controllers with a very simple SPI protocol: Only one
>> +byte will be sent. The value of the byte can be any value between the off-value
>> +and max-value defined in the properties.
>> +
>> +One example where the driver can be used is the controller in Ubiquiti airCube
>> +ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX
>> +8F26E611LA) that has been programmed to control the single LED of the device.
> 
> What about power control of the uC?

You mean if the uC receives a reset or power cycle independent of the
main controller? I don't think that this can happen on that board. But I
don't have any schematics to prove that.

> 
>> +The controller supports four modes depending on the highest two bits in a byte:
>> +One setting for brightness, the other three provide different blink patterns.
> 
> This part seems in no way generic.
> 
> How does one support the blink patterns?

You are correct that this part is not generic. But a multi-purpose
driver like the one I proposed could deliver a basic support for the
device by controlling the brightness.

It's only a basic support so the blink patterns are not supported.

I had a look at the functions in "struct led_classdev". There is a
blink_set(..) function that expects that delay_on and delay_off can be
set independent. That's not possible for hardware supported blinking on
this device. The other function pattern_set(..) would allow an even more
universal interface. All possible patterns of the LED could be covered
in that but I don't think that this is true the other way round.

So in my opinion the only thing that can be implemented in a useful way
for that controller is the brightness.

> 
>> +With the leds-spi-byte driver a basic support for the brightness mode of that
>> +controller can be easily achieved by setting the minimum and maximum to the
>> +brightness modes minimum and maximum byte value.
>> +
>> +Required properties:
>> +- compatible:          Should be "leds-spi-byte".
> 
> Generally, we don't do "generic" bindings like this. The exceptions
> are either we have confidence they really can be generic or they where
> created before we knew better. A sample size of 1 doesn't convince me
> the former is true.

I could construct another sample (some SPI-based digital potentiometer
where you set values between 17 and 213) but I doubt that it would be a
good idea to fight for the name.

My original target device is a quite special one: I don't have a chip
number. The controller Ubiquiti built here is based on a microcontroller
that could be anything. The general device is named "Ubiquiti airCube
ISP" or (a short form that I found at some locations) ubnt-acb-isp. I
assume that they used the same controller in the non-ISP-version but I
haven't checked that. So how about one of these:

- ubnt,spi-byte-led
- ubnt,spi-acb-led
- ubnt,acb-isp-led

Most likely I'll get the off-value and max-value based on the binding
name then (0 and 63 for that device). So I'll just remove the two
parameters then.

> 
> This comment *only* applies to the binding, not the driver. Specific
> bindings can easily be bound to generic drivers.
> 

So the driver should still be called spi-byte (or something similar)?

>> +
>> +Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
>> +apply. In particular, "reg" and "spi-max-frequency" properties must be given.
> 
> What's the SPI mode configuration?

For this controller the mode seems to be CPOL = 0, CPHA = 0 (clock low
when idle, data valid on rising edge). CS is active low. The values are
MSB first (otherwise it would be an odd counter). Note that this is
based on reverse engineering (just like the protocol). So it's just a
justified guess.

If you are really interested in a lot of details, you can have a look at
the analysis that I did on that controller here:

https://github.com/c-mauderer/openwrt-Ubiquity-Aircube-notes/blob/5eb66d274db32238fc3249748be3a0eb26d1c91b/notes/Notes.asciidoc#led-controller

> 
>> +
>> +The driver currently only supports one LED. The properties of the LED are
>> +configured in a sub-node in the device node.
>> +
>> +LED sub-node properties:
>> +- label:
>> +       see Documentation/devicetree/bindings/leds/common.txt
>> +- leds-spi-byte,off-value:
>> +       The SPI byte value that should be sent to switch the LED off. Has to be
>> +       smaller than max-value. Range: 0 to 254.
>> +- leds-spi-byte,max-value:
>> +       The SPI byte value that should be sent to set the LED to the maximum
>> +       brightness. Has to be bigger than off-value. Range: 1 to 255.
> 
> Can't we already express this with brightness-levels and
> num-interpolated-steps properties? Some reason those ended up in
> pwm-backlight.txt, but really could apply to any LED with level
> controls.

The parameters gave the minimum and maximum SPI byte that should be
sent. But like said above: If the binding is based on the device name,
these parameters can just be a look up table or something similar based
on the binding name in the driver. So I can remove them.

> 
> Rob
> 

Best regards

Christian

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 15:29           ` Christian Mauderer
@ 2019-05-06 17:40             ` Dan Murphy
  2019-05-06 19:12               ` Christian Mauderer
  0 siblings, 1 reply; 28+ messages in thread
From: Dan Murphy @ 2019-05-06 17:40 UTC (permalink / raw)
  To: Christian Mauderer, Pavel Machek
  Cc: linux-leds, devicetree, Jacek Anaszewski, Rob Herring,
	Mark Rutland

Christian

On 5/6/19 10:29 AM, Christian Mauderer wrote:
> On 06/05/2019 17:15, Pavel Machek wrote:
>> Hi!
>>
>>>> Of course it would have been possible to make it a lot more universal by
>>>> for example adding a prefix, a bit mask or other word lengths. But that
>>>> would have added a lot of complexity without any actual application.
>>>>
>>>
>>> I have to disagree here.  If this is supposed to be a universal SPI byte driver that
>>> needs special handling then it is either needs to be created in a universal way or needs to be made
>>> target specific.
>>>
>>
>> Let him be. The driver is good.
>>
>> If some hardware needs more flexibility, we add it.
>>
>> No need to have 1000 releases of everything.
>>
>> 									Pavel
>>
> 
> Hello Pavel,
> 
> thanks for the support.
> 
> It's a pure hobby project so I have the time to add useful features or
> to improve the description to make it clear what the drivers intention
> is. So if we find a more useful set of features it's a good idea to
> discuss it.
> 
> By the way: Although I haven't written a Linux driver yet it's not my
> first open source project. So I know that there can be a lot of
> different opinions and sometimes a lot of revisions. So no big risk of
> scaring me away.
> 

Hopefully the feedback from all is helping you with developing kernel drivers :).

One request though is can you slow down a bit in the versions?
I had 3 versions in my inbox before I had a chance to review v1.

I have been asked the same thing by someone and now I try to give at least 24-48 hours so others over seas
can get a chance to review prior to posting a new version.

Dan

> Best regards
> 
> Christian
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 16:28   ` Pavel Machek
@ 2019-05-06 17:44     ` Rob Herring
  2019-05-06 19:21       ` Christian Mauderer
  0 siblings, 1 reply; 28+ messages in thread
From: Rob Herring @ 2019-05-06 17:44 UTC (permalink / raw)
  To: Pavel Machek
  Cc: oss, Linux LED Subsystem, devicetree, Jacek Anaszewski,
	Dan Murphy, Mark Rutland

On Mon, May 6, 2019 at 11:28 AM Pavel Machek <pavel@ucw.cz> wrote:
>
> Hi!
>
> > > +* Single Byte SPI LED Device Driver.
> > > +
> > > +The driver can be used for controllers with a very simple SPI protocol: Only one
> > > +byte will be sent. The value of the byte can be any value between the off-value
> > > +and max-value defined in the properties.
> > > +
> > > +One example where the driver can be used is the controller in Ubiquiti airCube
> > > +ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX
> > > +8F26E611LA) that has been programmed to control the single LED of the device.
> >
> > What about power control of the uC?
> >
> > > +The controller supports four modes depending on the highest two bits in a byte:
> > > +One setting for brightness, the other three provide different blink patterns.
> >
> > This part seems in no way generic.
> >
> > How does one support the blink patterns?
> >
> > > +With the leds-spi-byte driver a basic support for the brightness mode of that
> > > +controller can be easily achieved by setting the minimum and maximum to the
> > > +brightness modes minimum and maximum byte value.
> > > +
> > > +Required properties:
> > > +- compatible:          Should be "leds-spi-byte".
> >
> > Generally, we don't do "generic" bindings like this. The exceptions
> > are either we have confidence they really can be generic or they where
> > created before we knew better. A sample size of 1 doesn't convince me
> > the former is true.
> >
> > This comment *only* applies to the binding, not the driver. Specific
> > bindings can easily be bound to generic drivers.
>
> Ok, I'm afraid I caused this. What should the compatible be, then?

Knowing nothing about the h/w other than the above description:
ubiquiti,aircube-leds

Not sure if that's a registered or correct vendor prefix though.

Rob

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 17:03   ` Christian Mauderer
@ 2019-05-06 17:59     ` Rob Herring
  2019-05-06 19:28       ` Christian Mauderer
  2019-05-06 19:06     ` Jacek Anaszewski
  1 sibling, 1 reply; 28+ messages in thread
From: Rob Herring @ 2019-05-06 17:59 UTC (permalink / raw)
  To: Christian Mauderer
  Cc: Linux LED Subsystem, devicetree, Jacek Anaszewski, Pavel Machek,
	Dan Murphy, Mark Rutland

On Mon, May 6, 2019 at 12:03 PM Christian Mauderer <oss@c-mauderer.de> wrote:
>
> On 06/05/2019 18:21, Rob Herring wrote:
> > On Sun, May 5, 2019 at 3:00 PM <oss@c-mauderer.de> wrote:
> >>
> >> From: Christian Mauderer <oss@c-mauderer.de>
> >>
> >> This patch adds the binding documentation for a simple SPI based LED
> >> controller which use only one byte for setting the brightness.
> >>
> >> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
> >> ---
> >>
> >> Changes compared to v2:
> >> - None
> >>
> >> Changes compared to v1:
> >> - rename ubnt-spi to leds-spi-byte
> >> - rename "ubnt-spi,off_bright" and "ubnt-spi,max_bright" to
> >>   "leds-spi-byte,off-value" and "leds-spi-byte,max-value" and mark them required
> >> - rename led-controller node to "led-controller"
> >> - extend description
> >> - remove SPI controller
> >> - use "white:status" for the example label
> >>
> >>
> >>  .../bindings/leds/leds-spi-byte.txt           | 47 +++++++++++++++++++
> >>  1 file changed, 47 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/leds/leds-spi-byte.txt
> >>
> >> diff --git a/Documentation/devicetree/bindings/leds/leds-spi-byte.txt b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
> >> new file mode 100644
> >> index 000000000000..1dd6ab03a56d
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
> >> @@ -0,0 +1,47 @@
> >> +* Single Byte SPI LED Device Driver.
> >> +
> >> +The driver can be used for controllers with a very simple SPI protocol: Only one
> >> +byte will be sent. The value of the byte can be any value between the off-value
> >> +and max-value defined in the properties.
> >> +
> >> +One example where the driver can be used is the controller in Ubiquiti airCube
> >> +ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX
> >> +8F26E611LA) that has been programmed to control the single LED of the device.
> >
> > What about power control of the uC?
>
> You mean if the uC receives a reset or power cycle independent of the
> main controller? I don't think that this can happen on that board. But I
> don't have any schematics to prove that.

I was really only pointing out potential issues around "generic"
bindings. The protocol interface is not the only thing.

> >> +The controller supports four modes depending on the highest two bits in a byte:
> >> +One setting for brightness, the other three provide different blink patterns.
> >
> > This part seems in no way generic.
> >
> > How does one support the blink patterns?
>
> You are correct that this part is not generic. But a multi-purpose
> driver like the one I proposed could deliver a basic support for the
> device by controlling the brightness.
>
> It's only a basic support so the blink patterns are not supported.

Then you would have to change/extend the binding when you want to
support that. With a specific compatible, you only need a driver
change.

> I had a look at the functions in "struct led_classdev". There is a
> blink_set(..) function that expects that delay_on and delay_off can be
> set independent. That's not possible for hardware supported blinking on
> this device. The other function pattern_set(..) would allow an even more
> universal interface. All possible patterns of the LED could be covered
> in that but I don't think that this is true the other way round.
>
> So in my opinion the only thing that can be implemented in a useful way
> for that controller is the brightness.

What the OS can support evolves and should be independent of the binding.

> >
> >> +With the leds-spi-byte driver a basic support for the brightness mode of that
> >> +controller can be easily achieved by setting the minimum and maximum to the
> >> +brightness modes minimum and maximum byte value.
> >> +
> >> +Required properties:
> >> +- compatible:          Should be "leds-spi-byte".
> >
> > Generally, we don't do "generic" bindings like this. The exceptions
> > are either we have confidence they really can be generic or they where
> > created before we knew better. A sample size of 1 doesn't convince me
> > the former is true.
>
> I could construct another sample (some SPI-based digital potentiometer
> where you set values between 17 and 213) but I doubt that it would be a
> good idea to fight for the name.
>
> My original target device is a quite special one: I don't have a chip
> number. The controller Ubiquiti built here is based on a microcontroller
> that could be anything. The general device is named "Ubiquiti airCube
> ISP" or (a short form that I found at some locations) ubnt-acb-isp. I
> assume that they used the same controller in the non-ISP-version but I
> haven't checked that. So how about one of these:
>
> - ubnt,spi-byte-led
> - ubnt,spi-acb-led
> - ubnt,acb-isp-led

ubnt,acb-spi-led perhaps as the order is usually <product|soc>-<sub device>.

Or the last one if you wanted to keep 'isp'.

>
> Most likely I'll get the off-value and max-value based on the binding
> name then (0 and 63 for that device). So I'll just remove the two
> parameters then.
>
> >
> > This comment *only* applies to the binding, not the driver. Specific
> > bindings can easily be bound to generic drivers.
> >
>
> So the driver should still be called spi-byte (or something similar)?

Yes, whatever the LED maintainers want there.

Rob

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 17:03   ` Christian Mauderer
  2019-05-06 17:59     ` Rob Herring
@ 2019-05-06 19:06     ` Jacek Anaszewski
  1 sibling, 0 replies; 28+ messages in thread
From: Jacek Anaszewski @ 2019-05-06 19:06 UTC (permalink / raw)
  To: Christian Mauderer, Rob Herring
  Cc: Linux LED Subsystem, devicetree, Pavel Machek, Dan Murphy,
	Mark Rutland

Hi Christian,

On 5/6/19 7:03 PM, Christian Mauderer wrote:
> On 06/05/2019 18:21, Rob Herring wrote:
>> On Sun, May 5, 2019 at 3:00 PM <oss@c-mauderer.de> wrote:
[...]
> 
> I had a look at the functions in "struct led_classdev". There is a
> blink_set(..) function that expects that delay_on and delay_off can be
> set independent. That's not possible for hardware supported blinking on
> this device. 

If delay_on and delay_off values are not supported by the hardware,
then blink_set should return -EINVAL, which will result in activating
software blink fallback for given LED class device.

-- 
Best regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver
  2019-05-06 17:40             ` Dan Murphy
@ 2019-05-06 19:12               ` Christian Mauderer
  0 siblings, 0 replies; 28+ messages in thread
From: Christian Mauderer @ 2019-05-06 19:12 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek
  Cc: linux-leds, devicetree, Jacek Anaszewski, Rob Herring,
	Mark Rutland

Hello Dan,

On 06/05/2019 19:40, Dan Murphy wrote:
> Christian
> 
> On 5/6/19 10:29 AM, Christian Mauderer wrote:
>> On 06/05/2019 17:15, Pavel Machek wrote:
>>> Hi!
>>>
>>>>> Of course it would have been possible to make it a lot more universal by
>>>>> for example adding a prefix, a bit mask or other word lengths. But that
>>>>> would have added a lot of complexity without any actual application.
>>>>>
>>>>
>>>> I have to disagree here.  If this is supposed to be a universal SPI byte driver that
>>>> needs special handling then it is either needs to be created in a universal way or needs to be made
>>>> target specific.
>>>>
>>>
>>> Let him be. The driver is good.
>>>
>>> If some hardware needs more flexibility, we add it.
>>>
>>> No need to have 1000 releases of everything.
>>>
>>> 									Pavel
>>>
>>
>> Hello Pavel,
>>
>> thanks for the support.
>>
>> It's a pure hobby project so I have the time to add useful features or
>> to improve the description to make it clear what the drivers intention
>> is. So if we find a more useful set of features it's a good idea to
>> discuss it.
>>
>> By the way: Although I haven't written a Linux driver yet it's not my
>> first open source project. So I know that there can be a lot of
>> different opinions and sometimes a lot of revisions. So no big risk of
>> scaring me away.
>>
> 
> Hopefully the feedback from all is helping you with developing kernel drivers :).

I hadn't expected a such big discussion for such a small driver. But
it's no problem. Part of my work is to develop drivers for a open source
real time operating system. So I'm used to discussions. The community is
only a lot smaller and the drivers are far less standardized than for Linux.

> 
> One request though is can you slow down a bit in the versions?
> I had 3 versions in my inbox before I had a chance to review v1.
> 
> I have been asked the same thing by someone and now I try to give at least 24-48 hours so others over seas
> can get a chance to review prior to posting a new version.

I planned to wait till the discussion cools down before creating a v4. I
only have been so fast because yesterday I had the impression that some
big changes are requested and therefore created a v2. After that the
feedback seemed to only need detail changes therefore v3. But I forgot
that it maybe would be a good idea to wait till Monday.

Best regards

Christian

>
> Dan
> 
>> Best regards
>>
>> Christian
>>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 17:44     ` Rob Herring
@ 2019-05-06 19:21       ` Christian Mauderer
  2019-05-06 20:25         ` Pavel Machek
  0 siblings, 1 reply; 28+ messages in thread
From: Christian Mauderer @ 2019-05-06 19:21 UTC (permalink / raw)
  To: Rob Herring, Pavel Machek
  Cc: Linux LED Subsystem, devicetree, Jacek Anaszewski, Dan Murphy,
	Mark Rutland

On 06/05/2019 19:44, Rob Herring wrote:
> On Mon, May 6, 2019 at 11:28 AM Pavel Machek <pavel@ucw.cz> wrote:
>>
>> Hi!
>>
>>>> +* Single Byte SPI LED Device Driver.
>>>> +
>>>> +The driver can be used for controllers with a very simple SPI protocol: Only one
>>>> +byte will be sent. The value of the byte can be any value between the off-value
>>>> +and max-value defined in the properties.
>>>> +
>>>> +One example where the driver can be used is the controller in Ubiquiti airCube
>>>> +ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX
>>>> +8F26E611LA) that has been programmed to control the single LED of the device.
>>>
>>> What about power control of the uC?
>>>
>>>> +The controller supports four modes depending on the highest two bits in a byte:
>>>> +One setting for brightness, the other three provide different blink patterns.
>>>
>>> This part seems in no way generic.
>>>
>>> How does one support the blink patterns?
>>>
>>>> +With the leds-spi-byte driver a basic support for the brightness mode of that
>>>> +controller can be easily achieved by setting the minimum and maximum to the
>>>> +brightness modes minimum and maximum byte value.
>>>> +
>>>> +Required properties:
>>>> +- compatible:          Should be "leds-spi-byte".
>>>
>>> Generally, we don't do "generic" bindings like this. The exceptions
>>> are either we have confidence they really can be generic or they where
>>> created before we knew better. A sample size of 1 doesn't convince me
>>> the former is true.
>>>
>>> This comment *only* applies to the binding, not the driver. Specific
>>> bindings can easily be bound to generic drivers.
>>
>> Ok, I'm afraid I caused this. What should the compatible be, then?
> 
> Knowing nothing about the h/w other than the above description:
> ubiquiti,aircube-leds
> 
> Not sure if that's a registered or correct vendor prefix though.
> 
> Rob
> 

Where would such a vendor prefix be registered? Does that mean that only
the vendor is allowed to use it? In that case: How would a reverse
engineered prefix look like?

Regarding the vendor: I wanted to have support for the airCube in
OpenWRT. When I started working with the device I asked Ubiquiti for the
sources (they use a OpenWRT based system). I received more or less the
answer that they don't have an archive but of course would create one.
But they have no ETA for it. The hardware is quite similar to other
boards so after some weeks I just analysed all necessary and did the
port myself instead of fighting with the support. So something like
three months after my question to the support, I finished the patches
and they had been accepted to OpenWRT. Ubiquiti released a GPL archive
(still with some missing parts like U-Boot) about two weeks later. I had
a look at it and they are not using a device tree. So there is no
"official" string that I could deduce from that archive.

Best regards

Christian

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 17:59     ` Rob Herring
@ 2019-05-06 19:28       ` Christian Mauderer
  0 siblings, 0 replies; 28+ messages in thread
From: Christian Mauderer @ 2019-05-06 19:28 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linux LED Subsystem, devicetree, Jacek Anaszewski, Pavel Machek,
	Dan Murphy, Mark Rutland

On 06/05/2019 19:59, Rob Herring wrote:
> On Mon, May 6, 2019 at 12:03 PM Christian Mauderer <oss@c-mauderer.de> wrote:
>>
>> On 06/05/2019 18:21, Rob Herring wrote:
>>> On Sun, May 5, 2019 at 3:00 PM <oss@c-mauderer.de> wrote:
>>>>
>>>> From: Christian Mauderer <oss@c-mauderer.de>
>>>>
>>>> This patch adds the binding documentation for a simple SPI based LED
>>>> controller which use only one byte for setting the brightness.
>>>>
>>>> Signed-off-by: Christian Mauderer <oss@c-mauderer.de>
>>>> ---
>>>>
>>>> Changes compared to v2:
>>>> - None
>>>>
>>>> Changes compared to v1:
>>>> - rename ubnt-spi to leds-spi-byte
>>>> - rename "ubnt-spi,off_bright" and "ubnt-spi,max_bright" to
>>>>   "leds-spi-byte,off-value" and "leds-spi-byte,max-value" and mark them required
>>>> - rename led-controller node to "led-controller"
>>>> - extend description
>>>> - remove SPI controller
>>>> - use "white:status" for the example label
>>>>
>>>>
>>>>  .../bindings/leds/leds-spi-byte.txt           | 47 +++++++++++++++++++
>>>>  1 file changed, 47 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/leds/leds-spi-byte.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-spi-byte.txt b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
>>>> new file mode 100644
>>>> index 000000000000..1dd6ab03a56d
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt
>>>> @@ -0,0 +1,47 @@
>>>> +* Single Byte SPI LED Device Driver.
>>>> +
>>>> +The driver can be used for controllers with a very simple SPI protocol: Only one
>>>> +byte will be sent. The value of the byte can be any value between the off-value
>>>> +and max-value defined in the properties.
>>>> +
>>>> +One example where the driver can be used is the controller in Ubiquiti airCube
>>>> +ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX
>>>> +8F26E611LA) that has been programmed to control the single LED of the device.
>>>
>>> What about power control of the uC?
>>
>> You mean if the uC receives a reset or power cycle independent of the
>> main controller? I don't think that this can happen on that board. But I
>> don't have any schematics to prove that.
> 
> I was really only pointing out potential issues around "generic"
> bindings. The protocol interface is not the only thing.

OK.

> 
>>>> +The controller supports four modes depending on the highest two bits in a byte:
>>>> +One setting for brightness, the other three provide different blink patterns.
>>>
>>> This part seems in no way generic.
>>>
>>> How does one support the blink patterns?
>>
>> You are correct that this part is not generic. But a multi-purpose
>> driver like the one I proposed could deliver a basic support for the
>> device by controlling the brightness.
>>
>> It's only a basic support so the blink patterns are not supported.
> 
> Then you would have to change/extend the binding when you want to
> support that. With a specific compatible, you only need a driver
> change.

Accepted.

> 
>> I had a look at the functions in "struct led_classdev". There is a
>> blink_set(..) function that expects that delay_on and delay_off can be
>> set independent. That's not possible for hardware supported blinking on
>> this device. The other function pattern_set(..) would allow an even more
>> universal interface. All possible patterns of the LED could be covered
>> in that but I don't think that this is true the other way round.
>>
>> So in my opinion the only thing that can be implemented in a useful way
>> for that controller is the brightness.
> 
> What the OS can support evolves and should be independent of the binding.
> 

Yes OK. I maybe have seen the binding too tightly coupled.

>>>
>>>> +With the leds-spi-byte driver a basic support for the brightness mode of that
>>>> +controller can be easily achieved by setting the minimum and maximum to the
>>>> +brightness modes minimum and maximum byte value.
>>>> +
>>>> +Required properties:
>>>> +- compatible:          Should be "leds-spi-byte".
>>>
>>> Generally, we don't do "generic" bindings like this. The exceptions
>>> are either we have confidence they really can be generic or they where
>>> created before we knew better. A sample size of 1 doesn't convince me
>>> the former is true.
>>
>> I could construct another sample (some SPI-based digital potentiometer
>> where you set values between 17 and 213) but I doubt that it would be a
>> good idea to fight for the name.
>>
>> My original target device is a quite special one: I don't have a chip
>> number. The controller Ubiquiti built here is based on a microcontroller
>> that could be anything. The general device is named "Ubiquiti airCube
>> ISP" or (a short form that I found at some locations) ubnt-acb-isp. I
>> assume that they used the same controller in the non-ISP-version but I
>> haven't checked that. So how about one of these:
>>
>> - ubnt,spi-byte-led
>> - ubnt,spi-acb-led
>> - ubnt,acb-isp-led
> 
> ubnt,acb-spi-led perhaps as the order is usually <product|soc>-<sub device>.
> 
> Or the last one if you wanted to keep 'isp'.
> 

In your other mail you said that maybe a vendor prefix is registered.
See my questions regarding that there.

>>
>> Most likely I'll get the off-value and max-value based on the binding
>> name then (0 and 63 for that device). So I'll just remove the two
>> parameters then.
>>
>>>
>>> This comment *only* applies to the binding, not the driver. Specific
>>> bindings can easily be bound to generic drivers.
>>>
>>
>> So the driver should still be called spi-byte (or something similar)?
> 
> Yes, whatever the LED maintainers want there.

OK. I'll discuss that with them as soon as the binding is clear.

> 
> Rob
> 

Best regards

Christian

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 19:21       ` Christian Mauderer
@ 2019-05-06 20:25         ` Pavel Machek
  2019-05-07  9:52           ` Christian Mauderer
  0 siblings, 1 reply; 28+ messages in thread
From: Pavel Machek @ 2019-05-06 20:25 UTC (permalink / raw)
  To: Christian Mauderer
  Cc: Rob Herring, Linux LED Subsystem, devicetree, Jacek Anaszewski,
	Dan Murphy, Mark Rutland

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

Hi!

> >> Ok, I'm afraid I caused this. What should the compatible be, then?
> > 
> > Knowing nothing about the h/w other than the above description:
> > ubiquiti,aircube-leds
> > 
> > Not sure if that's a registered or correct vendor prefix though.
> > 
> > Rob
> > 
> 
> Where would such a vendor prefix be registered? Does that mean that only
> the vendor is allowed to use it? In that case: How would a reverse
> engineered prefix look like?

You can use it, too. It is in
Documentation/devicetree/bindings/vendor-prefixes.txt :

ubnt    Ubiquiti Networks

So you can probably use ubnt, prefix.

> (still with some missing parts like U-Boot) about two weeks later. I had
> a look at it and they are not using a device tree. So there is no
> "official" string that I could deduce from that archive.

Mainline is the master. You are more "official" than them ;-).
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-06 20:25         ` Pavel Machek
@ 2019-05-07  9:52           ` Christian Mauderer
  2019-05-10 19:50             ` Christian Mauderer
  0 siblings, 1 reply; 28+ messages in thread
From: Christian Mauderer @ 2019-05-07  9:52 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Rob Herring, Linux LED Subsystem, devicetree, Jacek Anaszewski,
	Dan Murphy, Mark Rutland

On 06/05/2019 22:25, Pavel Machek wrote:
> Hi!
> 
>>>> Ok, I'm afraid I caused this. What should the compatible be, then?
>>>
>>> Knowing nothing about the h/w other than the above description:
>>> ubiquiti,aircube-leds
>>>
>>> Not sure if that's a registered or correct vendor prefix though.
>>>
>>> Rob
>>>
>>
>> Where would such a vendor prefix be registered? Does that mean that only
>> the vendor is allowed to use it? In that case: How would a reverse
>> engineered prefix look like?
> 
> You can use it, too. It is in
> Documentation/devicetree/bindings/vendor-prefixes.txt :
> 
> ubnt    Ubiquiti Networks
> 
> So you can probably use ubnt, prefix.
> 
>> (still with some missing parts like U-Boot) about two weeks later. I had
>> a look at it and they are not using a device tree. So there is no
>> "official" string that I could deduce from that archive.
> 
> Mainline is the master. You are more "official" than them ;-).
> 									Pavel
> 

Hello

let me summarize the direction before I create a v4:

Rob Herring suggested "ubnt,acb-spi-led" for the binding name in his
Mail from 06.05.2019 17:59 UTC. If no one objects, I'll use that.

With the more specific name I'll remove the off-value and max-value from
the device tree. Instead I'll create some look up table in the driver.
based on the name or go back to the defines like in the v1 patch. What
kind of solution would be preferable depends on the next question:

How should I name the driver? Should I use a device specific name like
in v1 again (most likely now acb-spi-led)? That would allow to
potentially add a hardware supported blinking in that driver. The
alternative would be the more generic name that it has now
(leds-spi-byte) without any plans to add the blinking but it could be
potentially used for example for a digital potentiometer based
brightness setting.

Note that I didn't really had planned to implement the blinking support
because I don't have a use case for it. So it would be either a feature
that I would add because someone insists. Or it could be added in the
future by a user who wants that feature (maybe Ubiquiti when they
upgrade their kernel?).

If it is a required feature for that driver: Please note that although
of course I would do some basic tests during development it would be a
mostly unused and therefore untested feature.

Best regards

Christian

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-07  9:52           ` Christian Mauderer
@ 2019-05-10 19:50             ` Christian Mauderer
  2019-05-10 20:42               ` Jacek Anaszewski
  0 siblings, 1 reply; 28+ messages in thread
From: Christian Mauderer @ 2019-05-10 19:50 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Rob Herring, Linux LED Subsystem, devicetree, Jacek Anaszewski,
	Dan Murphy, Mark Rutland

On 07/05/2019 11:52, Christian Mauderer wrote:
> On 06/05/2019 22:25, Pavel Machek wrote:
>> Hi!
>>
>>>>> Ok, I'm afraid I caused this. What should the compatible be, then?
>>>>
>>>> Knowing nothing about the h/w other than the above description:
>>>> ubiquiti,aircube-leds
>>>>
>>>> Not sure if that's a registered or correct vendor prefix though.
>>>>
>>>> Rob
>>>>
>>>
>>> Where would such a vendor prefix be registered? Does that mean that only
>>> the vendor is allowed to use it? In that case: How would a reverse
>>> engineered prefix look like?
>>
>> You can use it, too. It is in
>> Documentation/devicetree/bindings/vendor-prefixes.txt :
>>
>> ubnt    Ubiquiti Networks
>>
>> So you can probably use ubnt, prefix.
>>
>>> (still with some missing parts like U-Boot) about two weeks later. I had
>>> a look at it and they are not using a device tree. So there is no
>>> "official" string that I could deduce from that archive.
>>
>> Mainline is the master. You are more "official" than them ;-).
>> 									Pavel
>>
> 
> Hello
> 
> let me summarize the direction before I create a v4:
> 
> Rob Herring suggested "ubnt,acb-spi-led" for the binding name in his
> Mail from 06.05.2019 17:59 UTC. If no one objects, I'll use that.
> 
> With the more specific name I'll remove the off-value and max-value from
> the device tree. Instead I'll create some look up table in the driver.
> based on the name or go back to the defines like in the v1 patch. What
> kind of solution would be preferable depends on the next question:
> 
> How should I name the driver? Should I use a device specific name like
> in v1 again (most likely now acb-spi-led)? That would allow to
> potentially add a hardware supported blinking in that driver. The
> alternative would be the more generic name that it has now
> (leds-spi-byte) without any plans to add the blinking but it could be
> potentially used for example for a digital potentiometer based
> brightness setting.
> 
> Note that I didn't really had planned to implement the blinking support
> because I don't have a use case for it. So it would be either a feature
> that I would add because someone insists. Or it could be added in the
> future by a user who wants that feature (maybe Ubiquiti when they
> upgrade their kernel?).
> 
> If it is a required feature for that driver: Please note that although
> of course I would do some basic tests during development it would be a
> mostly unused and therefore untested feature.
> 
> Best regards
> 
> Christian
> 

Hello,

sorry for repeating my question. I assume I wrote to much text hiding
it: How should I name the driver?

The name for the binding is clear (ubnt,acb-spi-led). Only the driver is
left (keep leds-spi-byte or rename to leds-ubnt-acb-spi or something else).

Best regards

Christian

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-10 19:50             ` Christian Mauderer
@ 2019-05-10 20:42               ` Jacek Anaszewski
  2019-05-11  6:56                 ` Christian Mauderer
  0 siblings, 1 reply; 28+ messages in thread
From: Jacek Anaszewski @ 2019-05-10 20:42 UTC (permalink / raw)
  To: Christian Mauderer, Pavel Machek
  Cc: Rob Herring, Linux LED Subsystem, devicetree, Dan Murphy,
	Mark Rutland

Hi Christian,

On 5/10/19 9:50 PM, Christian Mauderer wrote:
> On 07/05/2019 11:52, Christian Mauderer wrote:
>> On 06/05/2019 22:25, Pavel Machek wrote:
>>> Hi!
>>>
>>>>>> Ok, I'm afraid I caused this. What should the compatible be, then?
>>>>>
>>>>> Knowing nothing about the h/w other than the above description:
>>>>> ubiquiti,aircube-leds
>>>>>
>>>>> Not sure if that's a registered or correct vendor prefix though.
>>>>>
>>>>> Rob
>>>>>
>>>>
>>>> Where would such a vendor prefix be registered? Does that mean that only
>>>> the vendor is allowed to use it? In that case: How would a reverse
>>>> engineered prefix look like?
>>>
>>> You can use it, too. It is in
>>> Documentation/devicetree/bindings/vendor-prefixes.txt :
>>>
>>> ubnt    Ubiquiti Networks
>>>
>>> So you can probably use ubnt, prefix.
>>>
>>>> (still with some missing parts like U-Boot) about two weeks later. I had
>>>> a look at it and they are not using a device tree. So there is no
>>>> "official" string that I could deduce from that archive.
>>>
>>> Mainline is the master. You are more "official" than them ;-).
>>> 									Pavel
>>>
>>
>> Hello
>>
>> let me summarize the direction before I create a v4:
>>
>> Rob Herring suggested "ubnt,acb-spi-led" for the binding name in his
>> Mail from 06.05.2019 17:59 UTC. If no one objects, I'll use that.
>>
>> With the more specific name I'll remove the off-value and max-value from
>> the device tree. Instead I'll create some look up table in the driver.
>> based on the name or go back to the defines like in the v1 patch. What
>> kind of solution would be preferable depends on the next question:
>>
>> How should I name the driver? Should I use a device specific name like
>> in v1 again (most likely now acb-spi-led)? That would allow to
>> potentially add a hardware supported blinking in that driver. The
>> alternative would be the more generic name that it has now
>> (leds-spi-byte) without any plans to add the blinking but it could be
>> potentially used for example for a digital potentiometer based
>> brightness setting.
>>
>> Note that I didn't really had planned to implement the blinking support
>> because I don't have a use case for it. So it would be either a feature
>> that I would add because someone insists. Or it could be added in the
>> future by a user who wants that feature (maybe Ubiquiti when they
>> upgrade their kernel?).
>>
>> If it is a required feature for that driver: Please note that although
>> of course I would do some basic tests during development it would be a
>> mostly unused and therefore untested feature.
>>
>> Best regards
>>
>> Christian
>>
> 
> Hello,
> 
> sorry for repeating my question. I assume I wrote to much text hiding
> it: How should I name the driver?
> 
> The name for the binding is clear (ubnt,acb-spi-led). Only the driver is
> left (keep leds-spi-byte or rename to leds-ubnt-acb-spi or something else).

Why leds-spi-byte name would prevent addition of blink support? It can
be always added basing on OF compatible. If it is to be generic SPI
byte driver, then I'd use leds-spi-byte. Actually also the things
like allowed brightness levels could be determined basing on that,
and not in device tree, but in the driver.

Please compare how e.g. drivers/leds/leds-is31fl32xx.c accomplishes
that.

-- 
Best regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-10 20:42               ` Jacek Anaszewski
@ 2019-05-11  6:56                 ` Christian Mauderer
  2019-05-11  9:11                   ` Jacek Anaszewski
  0 siblings, 1 reply; 28+ messages in thread
From: Christian Mauderer @ 2019-05-11  6:56 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Rob Herring, Linux LED Subsystem, devicetree, Dan Murphy,
	Mark Rutland

Hello Jacek,

On 10/05/2019 22:42, Jacek Anaszewski wrote:
> Hi Christian,
> 
> On 5/10/19 9:50 PM, Christian Mauderer wrote:
>> On 07/05/2019 11:52, Christian Mauderer wrote:
>>> On 06/05/2019 22:25, Pavel Machek wrote:
>>>> Hi!
>>>>
>>>>>>> Ok, I'm afraid I caused this. What should the compatible be, then?
>>>>>>
>>>>>> Knowing nothing about the h/w other than the above description:
>>>>>> ubiquiti,aircube-leds
>>>>>>
>>>>>> Not sure if that's a registered or correct vendor prefix though.
>>>>>>
>>>>>> Rob
>>>>>>
>>>>>
>>>>> Where would such a vendor prefix be registered? Does that mean that
>>>>> only
>>>>> the vendor is allowed to use it? In that case: How would a reverse
>>>>> engineered prefix look like?
>>>>
>>>> You can use it, too. It is in
>>>> Documentation/devicetree/bindings/vendor-prefixes.txt :
>>>>
>>>> ubnt��� Ubiquiti Networks
>>>>
>>>> So you can probably use ubnt, prefix.
>>>>
>>>>> (still with some missing parts like U-Boot) about two weeks later.
>>>>> I had
>>>>> a look at it and they are not using a device tree. So there is no
>>>>> "official" string that I could deduce from that archive.
>>>>
>>>> Mainline is the master. You are more "official" than them ;-).
>>>> ����������������������������������� Pavel
>>>>
>>>
>>> Hello
>>>
>>> let me summarize the direction before I create a v4:
>>>
>>> Rob Herring suggested "ubnt,acb-spi-led" for the binding name in his
>>> Mail from 06.05.2019 17:59 UTC. If no one objects, I'll use that.
>>>
>>> With the more specific name I'll remove the off-value and max-value from
>>> the device tree. Instead I'll create some look up table in the driver.
>>> based on the name or go back to the defines like in the v1 patch. What
>>> kind of solution would be preferable depends on the next question:
>>>
>>> How should I name the driver? Should I use a device specific name like
>>> in v1 again (most likely now acb-spi-led)? That would allow to
>>> potentially add a hardware supported blinking in that driver. The
>>> alternative would be the more generic name that it has now
>>> (leds-spi-byte) without any plans to add the blinking but it could be
>>> potentially used for example for a digital potentiometer based
>>> brightness setting.
>>>
>>> Note that I didn't really had planned to implement the blinking support
>>> because I don't have a use case for it. So it would be either a feature
>>> that I would add because someone insists. Or it could be added in the
>>> future by a user who wants that feature (maybe Ubiquiti when they
>>> upgrade their kernel?).
>>>
>>> If it is a required feature for that driver: Please note that although
>>> of course I would do some basic tests during development it would be a
>>> mostly unused and therefore untested feature.
>>>
>>> Best regards
>>>
>>> Christian
>>>
>>
>> Hello,
>>
>> sorry for repeating my question. I assume I wrote to much text hiding
>> it: How should I name the driver?
>>
>> The name for the binding is clear (ubnt,acb-spi-led). Only the driver is
>> left (keep leds-spi-byte or rename to leds-ubnt-acb-spi or something
>> else).
> 
> Why leds-spi-byte name would prevent addition of blink support? It can
> be always added basing on OF compatible. If it is to be generic SPI
> byte driver, then I'd use leds-spi-byte. Actually also the things
> like allowed brightness levels could be determined basing on that,
> and not in device tree, but in the driver.
> 
> Please compare how e.g. drivers/leds/leds-is31fl32xx.c accomplishes
> that.
> 

I would have expected that adding a lot of device specific code (in that
case blinking) to a multi-purpose driver would be bad style. But I'll go
for the generic name if that is the accepted way. I already mentioned
multiple times that my target is currently only the brightness. So the
device specific code maybe is added quite a bit in the future anyway in
which case it would still be possible to rename a part (if it isn't used
otherwise) or at least split it into it's own c-file.

I'll prepare a v4 in the near future and send it to the list. I only
learned that it would be a good idea to wait for at least a day for some
other opinions before doing that ;-)

Best regards

Christian

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED.
  2019-05-11  6:56                 ` Christian Mauderer
@ 2019-05-11  9:11                   ` Jacek Anaszewski
  0 siblings, 0 replies; 28+ messages in thread
From: Jacek Anaszewski @ 2019-05-11  9:11 UTC (permalink / raw)
  To: Christian Mauderer, Pavel Machek
  Cc: Rob Herring, Linux LED Subsystem, devicetree, Dan Murphy,
	Mark Rutland

On 5/11/19 8:56 AM, Christian Mauderer wrote:
> Hello Jacek,
> 
> On 10/05/2019 22:42, Jacek Anaszewski wrote:
>> Hi Christian,
>>
>> On 5/10/19 9:50 PM, Christian Mauderer wrote:
>>> On 07/05/2019 11:52, Christian Mauderer wrote:
>>>> On 06/05/2019 22:25, Pavel Machek wrote:
>>>>> Hi!
>>>>>
>>>>>>>> Ok, I'm afraid I caused this. What should the compatible be, then?
>>>>>>>
>>>>>>> Knowing nothing about the h/w other than the above description:
>>>>>>> ubiquiti,aircube-leds
>>>>>>>
>>>>>>> Not sure if that's a registered or correct vendor prefix though.
>>>>>>>
>>>>>>> Rob
>>>>>>>
>>>>>>
>>>>>> Where would such a vendor prefix be registered? Does that mean that
>>>>>> only
>>>>>> the vendor is allowed to use it? In that case: How would a reverse
>>>>>> engineered prefix look like?
>>>>>
>>>>> You can use it, too. It is in
>>>>> Documentation/devicetree/bindings/vendor-prefixes.txt :
>>>>>
>>>>> ubnt��� Ubiquiti Networks
>>>>>
>>>>> So you can probably use ubnt, prefix.
>>>>>
>>>>>> (still with some missing parts like U-Boot) about two weeks later.
>>>>>> I had
>>>>>> a look at it and they are not using a device tree. So there is no
>>>>>> "official" string that I could deduce from that archive.
>>>>>
>>>>> Mainline is the master. You are more "official" than them ;-).
>>>>>  ����������������������������������� Pavel
>>>>>
>>>>
>>>> Hello
>>>>
>>>> let me summarize the direction before I create a v4:
>>>>
>>>> Rob Herring suggested "ubnt,acb-spi-led" for the binding name in his
>>>> Mail from 06.05.2019 17:59 UTC. If no one objects, I'll use that.
>>>>
>>>> With the more specific name I'll remove the off-value and max-value from
>>>> the device tree. Instead I'll create some look up table in the driver.
>>>> based on the name or go back to the defines like in the v1 patch. What
>>>> kind of solution would be preferable depends on the next question:
>>>>
>>>> How should I name the driver? Should I use a device specific name like
>>>> in v1 again (most likely now acb-spi-led)? That would allow to
>>>> potentially add a hardware supported blinking in that driver. The
>>>> alternative would be the more generic name that it has now
>>>> (leds-spi-byte) without any plans to add the blinking but it could be
>>>> potentially used for example for a digital potentiometer based
>>>> brightness setting.
>>>>
>>>> Note that I didn't really had planned to implement the blinking support
>>>> because I don't have a use case for it. So it would be either a feature
>>>> that I would add because someone insists. Or it could be added in the
>>>> future by a user who wants that feature (maybe Ubiquiti when they
>>>> upgrade their kernel?).
>>>>
>>>> If it is a required feature for that driver: Please note that although
>>>> of course I would do some basic tests during development it would be a
>>>> mostly unused and therefore untested feature.
>>>>
>>>> Best regards
>>>>
>>>> Christian
>>>>
>>>
>>> Hello,
>>>
>>> sorry for repeating my question. I assume I wrote to much text hiding
>>> it: How should I name the driver?
>>>
>>> The name for the binding is clear (ubnt,acb-spi-led). Only the driver is
>>> left (keep leds-spi-byte or rename to leds-ubnt-acb-spi or something
>>> else).
>>
>> Why leds-spi-byte name would prevent addition of blink support? It can
>> be always added basing on OF compatible. If it is to be generic SPI
>> byte driver, then I'd use leds-spi-byte. Actually also the things
>> like allowed brightness levels could be determined basing on that,
>> and not in device tree, but in the driver.
>>
>> Please compare how e.g. drivers/leds/leds-is31fl32xx.c accomplishes
>> that.
>>
> 
> I would have expected that adding a lot of device specific code (in that
> case blinking) to a multi-purpose driver would be bad style.

This is a matter of how much customizable the driver is going to be.
It can serve as a nice code base for other devices with simple
SPI-based protocol.

> But I'll go
> for the generic name if that is the accepted way. I already mentioned
> multiple times that my target is currently only the brightness. So the
> device specific code maybe is added quite a bit in the future anyway in
> which case it would still be possible to rename a part (if it isn't used
> otherwise) or at least split it into it's own c-file.
> 
> I'll prepare a v4 in the near future and send it to the list. I only
> learned that it would be a good idea to wait for at least a day for some
> other opinions before doing that ;-)

Sure thing. The fact that I'm replying to your message doesn't mean
I'm expecting your immediate reaction :-)

-- 
Best regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2019-05-11  9:11 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-05 20:00 [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED oss
2019-05-05 20:00 ` [PATCH v3 2/2] leds: spi-byte: add single byte SPI LED driver oss
2019-05-05 20:09   ` Jacek Anaszewski
2019-05-05 20:14     ` Christian Mauderer
2019-05-06 12:05   ` Dan Murphy
2019-05-06 12:59     ` Christian Mauderer
2019-05-06 14:58       ` Dan Murphy
2019-05-06 15:15         ` Pavel Machek
2019-05-06 15:29           ` Christian Mauderer
2019-05-06 17:40             ` Dan Murphy
2019-05-06 19:12               ` Christian Mauderer
2019-05-06 15:19         ` Christian Mauderer
2019-05-06 15:37           ` Dan Murphy
2019-05-06 15:42             ` Christian Mauderer
2019-05-06 16:21 ` [PATCH v3 1/2] dt-bindings: leds: Add binding for spi-byte LED Rob Herring
2019-05-06 16:28   ` Pavel Machek
2019-05-06 17:44     ` Rob Herring
2019-05-06 19:21       ` Christian Mauderer
2019-05-06 20:25         ` Pavel Machek
2019-05-07  9:52           ` Christian Mauderer
2019-05-10 19:50             ` Christian Mauderer
2019-05-10 20:42               ` Jacek Anaszewski
2019-05-11  6:56                 ` Christian Mauderer
2019-05-11  9:11                   ` Jacek Anaszewski
2019-05-06 17:03   ` Christian Mauderer
2019-05-06 17:59     ` Rob Herring
2019-05-06 19:28       ` Christian Mauderer
2019-05-06 19:06     ` Jacek Anaszewski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).