Linux-LEDs Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/2] LP5024/18 LED introduction
@ 2018-12-19 16:26 Dan Murphy
  2018-12-19 16:26 ` [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver Dan Murphy
                   ` (2 more replies)
  0 siblings, 3 replies; 106+ messages in thread
From: Dan Murphy @ 2018-12-19 16:26 UTC (permalink / raw)
  To: robh+dt, jacek.anaszewski, pavel
  Cc: devicetree, linux-kernel, linux-leds, Dan Murphy

Hello

I am introducing the newest of the TI RGB parts the LP5024 and the LP5018.
Now I understand that there is a patchset in the works that changes the way
the LED labeling is created but I wanted to post these patches for comments and
let the maintainers decide whether to pull this in prior to that patchset being
committed.

Dan

Dan Murphy (2):
  dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  leds: lp5024: Add the LP5024/18 RGB LED driver

 .../devicetree/bindings/leds/leds-lp5024.txt  |  63 ++
 drivers/leds/Kconfig                          |   7 +
 drivers/leds/Makefile                         |   1 +
 drivers/leds/leds-lp5024.c                    | 610 ++++++++++++++++++
 4 files changed, 681 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
 create mode 100644 drivers/leds/leds-lp5024.c

-- 
2.20.0.rc2.7.g965798d1f2

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

* [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2018-12-19 16:26 [PATCH 0/2] LP5024/18 LED introduction Dan Murphy
@ 2018-12-19 16:26 ` Dan Murphy
  2018-12-28 23:53   ` Rob Herring
  2019-01-08 20:33   ` Jacek Anaszewski
  2018-12-19 16:26 ` [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver Dan Murphy
  2019-07-22 20:59 ` Backlight in motorola Droid 4 Pavel Machek
  2 siblings, 2 replies; 106+ messages in thread
From: Dan Murphy @ 2018-12-19 16:26 UTC (permalink / raw)
  To: robh+dt, jacek.anaszewski, pavel
  Cc: devicetree, linux-kernel, linux-leds, Dan Murphy

Introduce the bindings for the Texas Instruments LP5024 and the LP5018
RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
or as part of a control bank group.  These devices have the ability
to adjust the mixing control for the RGB LEDs to obtain different colors
independent of the overall brightness of the LED grouping.

Datasheet:
http://www.ti.com/lit/ds/symlink/lp5024.pdf

Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
 .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt

diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
new file mode 100644
index 000000000000..9567aa6f7813
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
@@ -0,0 +1,63 @@
+* Texas Instruments - LP5024/18 RGB LED driver
+
+The LM3692x is an ultra-compact, highly efficient,
+white-LED driver designed for LCD display backlighting.
+
+The main difference between the LP5024 and L5018 is the number of
+RGB LEDs they support.  The LP5024 supports twenty four strings while the
+LP5018 supports eighteen strings.
+
+Required properties:
+	- compatible:
+		"ti,lp5018"
+		"ti,lp5024"
+	- reg :  I2C slave address
+	- #address-cells : 1
+	- #size-cells : 0
+
+Optional properties:
+	- enable-gpios : gpio pin to enable/disable the device.
+	- vled-supply : LED supply
+
+Required child properties:
+	- reg : Is the child node iteration.
+	- led-sources : LP5024 - 0 - 7
+			LP5018 - 0 - 5
+			Declares the LED string or strings that the child node
+			will control.  If ti,control-bank is set then this
+			property will contain multiple LED IDs.
+
+Optional child properties:
+	- label : see Documentation/devicetree/bindings/leds/common.txt
+	- linux,default-trigger :
+	   see Documentation/devicetree/bindings/leds/common.txt
+	- ti,control-bank : Indicates that the LED strings declared in the
+			    led-sources property are grouped within a control
+			    bank for brightness and mixing control.
+
+Example:
+
+led-controller@28 {
+	compatible = "ti,lp5024";
+	reg = <0x28>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+	vled-supply = <&vbatt>;
+
+	led@0 {
+		reg = <0>;
+		led-sources = <1>;
+	};
+
+	led@1 {
+		reg = <1>;
+		led-sources = <0 6>;
+		ti,control-bank;
+	};
+
+}
+
+For more product information please see the link below:
+http://www.ti.com/lit/ds/symlink/lp5024.pdf
-- 
2.20.0.rc2.7.g965798d1f2

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

* [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 16:26 [PATCH 0/2] LP5024/18 LED introduction Dan Murphy
  2018-12-19 16:26 ` [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver Dan Murphy
@ 2018-12-19 16:26 ` Dan Murphy
  2018-12-19 19:04   ` Dan Murphy
                     ` (2 more replies)
  2019-07-22 20:59 ` Backlight in motorola Droid 4 Pavel Machek
  2 siblings, 3 replies; 106+ messages in thread
From: Dan Murphy @ 2018-12-19 16:26 UTC (permalink / raw)
  To: robh+dt, jacek.anaszewski, pavel
  Cc: devicetree, linux-kernel, linux-leds, Dan Murphy

Introduce the LP5024 and LP5018 RGB LED driver.
The difference in these 2 parts are only in the number of
LED outputs where the LP5024 can control 24 LEDs the LP5018
can only control 18.

The device has the ability to group LED output into control banks
so that multiple LED banks can be controlled with the same mixing and
brightness.  Inversely the LEDs can also be controlled independently.

Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
 drivers/leds/Kconfig       |   7 +
 drivers/leds/Makefile      |   1 +
 drivers/leds/leds-lp5024.c | 610 +++++++++++++++++++++++++++++++++++++
 3 files changed, 618 insertions(+)
 create mode 100644 drivers/leds/leds-lp5024.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index a72f97fca57b..d306bedb00b7 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -326,6 +326,13 @@ config LEDS_LP3952
 	  To compile this driver as a module, choose M here: the
 	  module will be called leds-lp3952.
 
+config LEDS_LP5024
+	tristate "LED Support for TI LP5024/18 LED driver chip"
+	depends on LEDS_CLASS && REGMAP_I2C
+	help
+	  If you say yes here you get support for the Texas Instruments
+	  LP5024 and LP5018 LED driver.
+
 config LEDS_LP55XX_COMMON
 	tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501"
 	depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 4c1b0054f379..60b4e4ddd3ee 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_LEDS_GPIO_REGISTER)	+= leds-gpio-register.o
 obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
 obj-$(CONFIG_LEDS_LP3944)		+= leds-lp3944.o
 obj-$(CONFIG_LEDS_LP3952)		+= leds-lp3952.o
+obj-$(CONFIG_LEDS_LP5024)		+= leds-lp5024.o
 obj-$(CONFIG_LEDS_LP55XX_COMMON)	+= leds-lp55xx-common.o
 obj-$(CONFIG_LEDS_LP5521)		+= leds-lp5521.o
 obj-$(CONFIG_LEDS_LP5523)		+= leds-lp5523.o
diff --git a/drivers/leds/leds-lp5024.c b/drivers/leds/leds-lp5024.c
new file mode 100644
index 000000000000..90e8dca15609
--- /dev/null
+++ b/drivers/leds/leds-lp5024.c
@@ -0,0 +1,610 @@
+// SPDX-License-Identifier: GPL-2.0
+/* TI LP50XX LED chip family driver
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <uapi/linux/uleds.h>
+
+#define LP5024_DEV_CFG0		0x00
+#define LP5024_DEV_CFG1		0x01
+#define LP5024_LED_CFG0		0x02
+#define LP5024_BNK_BRT		0x03
+#define LP5024_BNKA_CLR		0x04
+#define LP5024_BNKB_CLR		0x05
+#define LP5024_BNKC_CLR		0x06
+#define LP5024_LED0_BRT		0x07
+#define LP5024_LED1_BRT		0x08
+#define LP5024_LED2_BRT		0x09
+#define LP5024_LED3_BRT		0x0a
+#define LP5024_LED4_BRT		0x0b
+#define LP5024_LED5_BRT		0x0c
+#define LP5024_LED6_BRT		0x0d
+#define LP5024_LED7_BRT		0x0e
+
+#define LP5024_OUT0_CLR		0x0f
+#define LP5024_OUT1_CLR		0x10
+#define LP5024_OUT2_CLR		0x11
+#define LP5024_OUT3_CLR		0x12
+#define LP5024_OUT4_CLR		0x13
+#define LP5024_OUT5_CLR		0x14
+#define LP5024_OUT6_CLR		0x15
+#define LP5024_OUT7_CLR		0x16
+#define LP5024_OUT8_CLR		0x17
+#define LP5024_OUT9_CLR		0x18
+#define LP5024_OUT10_CLR	0x19
+#define LP5024_OUT11_CLR	0x1a
+#define LP5024_OUT12_CLR	0x1b
+#define LP5024_OUT13_CLR	0x1c
+#define LP5024_OUT14_CLR	0x1d
+#define LP5024_OUT15_CLR	0x1e
+#define LP5024_OUT16_CLR	0x1f
+#define LP5024_OUT17_CLR	0x20
+#define LP5024_OUT18_CLR	0x21
+#define LP5024_OUT19_CLR	0x22
+#define LP5024_OUT20_CLR	0x23
+#define LP5024_OUT21_CLR	0x24
+#define LP5024_OUT22_CLR	0x25
+#define LP5024_OUT23_CLR	0x26
+
+#define LP5024_RESET		0x27
+#define LP5024_SW_RESET		0xff
+
+#define LP5024_CHIP_EN		BIT(6)
+
+#define LP5024_CONTROL_A		0
+#define LP5024_CONTROL_B		1
+#define LP5024_CONTROL_C		2
+#define LP5024_MAX_CONTROL_BANKS	3
+
+#define LP5018_MAX_LED_STRINGS	6
+#define LP5024_MAX_LED_STRINGS	8
+
+enum lp5024_model {
+	LP5018,
+	LP5024,
+};
+
+struct lp5024_led {
+	u32 led_strings[LP5024_MAX_LED_STRINGS];
+	char label[LED_MAX_NAME_SIZE];
+	struct led_classdev led_dev;
+	struct lp5024 *priv;
+	int led_number;
+	u8 ctrl_bank_enabled;
+};
+
+/**
+ * struct lp5024 -
+ * @enable_gpio: Hardware enable gpio
+ * @regulator: LED supply regulator pointer
+ * @client: Pointer to the I2C client
+ * @regmap: Devices register map
+ * @dev: Pointer to the devices device struct
+ * @lock: Lock for reading/writing the device
+ * @model_id: ID of the device
+ * @leds: Array of LED strings
+ */
+struct lp5024 {
+	struct gpio_desc *enable_gpio;
+	struct regulator *regulator;
+	struct i2c_client *client;
+	struct regmap *regmap;
+	struct device *dev;
+	struct mutex lock;
+	int model_id;
+	int max_leds;
+	int num_of_leds;
+
+	/* This needs to be at the end of the struct */
+	struct lp5024_led leds[];
+};
+
+static const struct reg_default lp5024_reg_defs[] = {
+	{LP5024_DEV_CFG0, 0x0},
+	{LP5024_DEV_CFG1, 0x3c},
+	{LP5024_BNK_BRT, 0xff},
+	{LP5024_BNKA_CLR, 0x0f},
+	{LP5024_BNKB_CLR, 0x0f},
+	{LP5024_BNKC_CLR, 0x0f},
+	{LP5024_LED0_BRT, 0x0f},
+	{LP5024_LED1_BRT, 0xff},
+	{LP5024_LED2_BRT, 0xff},
+	{LP5024_LED3_BRT, 0xff},
+	{LP5024_LED4_BRT, 0xff},
+	{LP5024_LED5_BRT, 0xff},
+	{LP5024_LED6_BRT, 0xff},
+	{LP5024_LED7_BRT, 0xff},
+	{LP5024_OUT0_CLR, 0x0f},
+	{LP5024_OUT1_CLR, 0x00},
+	{LP5024_OUT2_CLR, 0x00},
+	{LP5024_OUT3_CLR, 0x00},
+	{LP5024_OUT4_CLR, 0x00},
+	{LP5024_OUT5_CLR, 0x00},
+	{LP5024_OUT6_CLR, 0x00},
+	{LP5024_OUT7_CLR, 0x00},
+	{LP5024_OUT8_CLR, 0x00},
+	{LP5024_OUT9_CLR, 0x00},
+	{LP5024_OUT10_CLR, 0x00},
+	{LP5024_OUT11_CLR, 0x00},
+	{LP5024_OUT12_CLR, 0x00},
+	{LP5024_OUT13_CLR, 0x00},
+	{LP5024_OUT14_CLR, 0x00},
+	{LP5024_OUT15_CLR, 0x00},
+	{LP5024_OUT16_CLR, 0x00},
+	{LP5024_OUT17_CLR, 0x00},
+	{LP5024_OUT18_CLR, 0x00},
+	{LP5024_OUT19_CLR, 0x00},
+	{LP5024_OUT20_CLR, 0x00},
+	{LP5024_OUT21_CLR, 0x00},
+	{LP5024_OUT22_CLR, 0x00},
+	{LP5024_OUT23_CLR, 0x00},
+	{LP5024_RESET, 0x00}
+};
+
+static const struct regmap_config lp5024_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = LP5024_RESET,
+	.reg_defaults = lp5024_reg_defs,
+	.num_reg_defaults = ARRAY_SIZE(lp5024_reg_defs),
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static int lp5024_set_color_mix(struct lp5024_led *led, u8 color_reg,
+				u8 color_val)
+{
+	return regmap_write(led->priv->regmap, color_reg, color_val);
+}
+
+
+static ssize_t ctrl_bank_a_mix_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
+					      led_dev);
+	u8 mix_value;
+	int ret;
+
+	ret = kstrtou8(buf, 0, &mix_value);
+	if (ret)
+		return ret;
+
+	lp5024_set_color_mix(led, LP5024_BNKA_CLR, mix_value);
+
+	return size;
+}
+static ssize_t ctrl_bank_b_mix_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
+					      led_dev);
+	u8 mix_value;
+	int ret;
+
+	ret = kstrtou8(buf, 0, &mix_value);
+	if (ret)
+		return ret;
+
+	lp5024_set_color_mix(led, LP5024_BNKB_CLR, mix_value);
+
+	return size;
+}
+static ssize_t ctrl_bank_c_mix_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
+					      led_dev);
+	u8 mix_value;
+	int ret;
+
+	ret = kstrtou8(buf, 0, &mix_value);
+	if (ret)
+		return ret;
+
+	lp5024_set_color_mix(led, LP5024_BNKC_CLR, mix_value);
+
+	return size;
+}
+
+static DEVICE_ATTR_WO(ctrl_bank_a_mix);
+static DEVICE_ATTR_WO(ctrl_bank_b_mix);
+static DEVICE_ATTR_WO(ctrl_bank_c_mix);
+
+static struct attribute *lp5024_ctrl_bank_attrs[] = {
+	&dev_attr_ctrl_bank_a_mix.attr,
+	&dev_attr_ctrl_bank_b_mix.attr,
+	&dev_attr_ctrl_bank_c_mix.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
+
+static ssize_t led3_mix_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
+					      led_dev);
+	u8 mix_value;
+	u8 reg_value;
+	int ret;
+
+	ret = kstrtou8(buf, 0, &mix_value);
+	if (ret)
+		return ret;
+
+	reg_value = (led->led_number * 3) + LP5024_OUT2_CLR;
+
+	lp5024_set_color_mix(led, reg_value, mix_value);
+
+	return size;
+}
+
+static ssize_t led2_mix_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
+					      led_dev);
+	u8 mix_value;
+	u8 reg_value;
+	int ret;
+
+	ret = kstrtou8(buf, 0, &mix_value);
+	if (ret)
+		return ret;
+
+	reg_value = (led->led_number * 3) + LP5024_OUT1_CLR;
+
+	lp5024_set_color_mix(led, reg_value, mix_value);
+
+	return size;
+}
+
+static ssize_t led1_mix_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
+					      led_dev);
+	u8 mix_value;
+	u8 reg_value;
+	int ret;
+
+	ret = kstrtou8(buf, 0, &mix_value);
+	if (ret)
+		return ret;
+
+	reg_value = (led->led_number * 3) + LP5024_OUT0_CLR;
+
+	lp5024_set_color_mix(led, reg_value, mix_value);
+
+	return size;
+}
+
+static DEVICE_ATTR_WO(led1_mix);
+static DEVICE_ATTR_WO(led2_mix);
+static DEVICE_ATTR_WO(led3_mix);
+
+static struct attribute *lp5024_led_independent_attrs[] = {
+	&dev_attr_led1_mix.attr,
+	&dev_attr_led2_mix.attr,
+	&dev_attr_led3_mix.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(lp5024_led_independent);
+
+static int lp5024_brightness_set(struct led_classdev *led_cdev,
+				enum led_brightness brt_val)
+{
+	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
+					      led_dev);
+	int ret = 0;
+	u8 reg_val;
+
+	mutex_lock(&led->priv->lock);
+
+	if (led->ctrl_bank_enabled)
+		reg_val = LP5024_BNK_BRT;
+	else
+		reg_val = led->led_number + LP5024_LED0_BRT;
+
+	ret = regmap_write(led->priv->regmap, reg_val, brt_val);
+
+	mutex_unlock(&led->priv->lock);
+
+	return ret;
+}
+
+static enum led_brightness lp5024_brightness_get(struct led_classdev *led_cdev)
+{
+	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
+					      led_dev);
+	unsigned int brt_val;
+	u8 reg_val;
+	int ret;
+
+	mutex_lock(&led->priv->lock);
+
+	if (led->ctrl_bank_enabled)
+		reg_val = LP5024_BNK_BRT;
+	else
+		reg_val = led->led_number + LP5024_LED0_BRT;
+
+	ret = regmap_read(led->priv->regmap, reg_val, &brt_val);
+
+	mutex_unlock(&led->priv->lock);
+
+	return brt_val;
+}
+
+static int lp5024_set_led_values(struct lp5024 *priv)
+{
+	struct lp5024_led *led;
+	int i, j;
+	u8 led_ctrl_enable = 0;
+
+	for (i = 0; i <= priv->num_of_leds; i++) {
+		led = &priv->leds[i];
+		if (led->ctrl_bank_enabled) {
+			for (j = 0; j <= LP5024_MAX_LED_STRINGS - 1; j++)
+				led_ctrl_enable |= (1 << led->led_strings[j]);
+		}
+	}
+
+	regmap_write(priv->regmap, LP5024_LED_CFG0, led_ctrl_enable);
+
+	return 0;
+}
+
+static int lp5024_init(struct lp5024 *priv)
+{
+	int ret;
+
+	if (priv->enable_gpio) {
+		gpiod_direction_output(priv->enable_gpio, 1);
+	} else {
+		ret = regmap_write(priv->regmap, LP5024_RESET, LP5024_SW_RESET);
+		if (ret) {
+			dev_err(&priv->client->dev,
+				"Cannot reset the device\n");
+			goto out;
+		}
+	}
+
+	ret = lp5024_set_led_values(priv);
+	if (ret)
+		dev_err(&priv->client->dev, "Setting the CRTL bank failed\n");
+
+	ret = regmap_write(priv->regmap, LP5024_DEV_CFG0, LP5024_CHIP_EN);
+	if (ret) {
+		dev_err(&priv->client->dev, "Cannot write ctrl enable\n");
+		goto out;
+	}
+out:
+	return ret;
+}
+
+static int lp5024_probe_dt(struct lp5024 *priv)
+{
+	struct fwnode_handle *child = NULL;
+	struct lp5024_led *led;
+	const char *name;
+	int led_number;
+	size_t i = 0;
+	int ret;
+
+	priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
+						   "enable", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->enable_gpio)) {
+		ret = PTR_ERR(priv->enable_gpio);
+		dev_err(&priv->client->dev, "Failed to get enable gpio: %d\n",
+			ret);
+		return ret;
+	}
+
+	priv->regulator = devm_regulator_get(&priv->client->dev, "vled");
+	if (IS_ERR(priv->regulator))
+		priv->regulator = NULL;
+
+	if (priv->model_id == LP5018)
+		priv->max_leds = LP5018_MAX_LED_STRINGS;
+	else
+		priv->max_leds = LP5024_MAX_LED_STRINGS;
+
+	device_for_each_child_node(&priv->client->dev, child) {
+		led = &priv->leds[i];
+
+		if (fwnode_property_present(child, "ti,control-bank"))
+			led->ctrl_bank_enabled = 1;
+		else
+			led->ctrl_bank_enabled = 0;
+
+		if (led->ctrl_bank_enabled) {
+			ret = fwnode_property_read_u32_array(child,
+							     "led-sources",
+							     NULL, 0);
+			ret = fwnode_property_read_u32_array(child,
+							     "led-sources",
+							     led->led_strings,
+							     ret);
+
+			led->led_number = led->led_strings[0];
+
+		} else {
+			ret = fwnode_property_read_u32(child, "led-sources",
+					       &led_number);
+
+			led->led_number = led_number;
+		}
+		if (ret) {
+			dev_err(&priv->client->dev,
+				"led-sources property missing\n");
+			fwnode_handle_put(child);
+			goto child_out;
+		}
+
+		if (led_number > priv->max_leds) {
+			dev_err(&priv->client->dev,
+				"led-sources property is invalid\n");
+			ret = -EINVAL;
+			fwnode_handle_put(child);
+			goto child_out;
+		}
+
+		ret = fwnode_property_read_string(child, "label", &name);
+		if (ret)
+			snprintf(led->label, sizeof(led->label),
+				"%s::", priv->client->name);
+		else
+			snprintf(led->label, sizeof(led->label),
+				 "%s:%s", priv->client->name, name);
+
+		fwnode_property_read_string(child, "linux,default-trigger",
+				    &led->led_dev.default_trigger);
+
+		led->priv = priv;
+		led->led_dev.name = led->label;
+		led->led_dev.max_brightness = 255;
+		led->led_dev.brightness_set_blocking = lp5024_brightness_set;
+		led->led_dev.brightness_get = lp5024_brightness_get;
+
+		if (led->ctrl_bank_enabled)
+			led->led_dev.groups = lp5024_ctrl_bank_groups;
+		else
+			led->led_dev.groups = lp5024_led_independent_groups;
+
+		ret = devm_led_classdev_register(&priv->client->dev,
+						 &led->led_dev);
+		if (ret) {
+			dev_err(&priv->client->dev, "led register err: %d\n",
+				ret);
+			fwnode_handle_put(child);
+			goto child_out;
+		}
+		i++;
+	}
+	priv->num_of_leds = i;
+
+child_out:
+	return ret;
+}
+
+static int lp5024_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct lp5024 *led;
+	int count;
+	int ret;
+
+	count = device_get_child_node_count(&client->dev);
+	if (!count) {
+		dev_err(&client->dev, "LEDs are not defined in device tree!");
+		return -ENODEV;
+	}
+
+	led = devm_kzalloc(&client->dev, struct_size(led, leds, count),
+			   GFP_KERNEL);
+	if (!led)
+		return -ENOMEM;
+
+	mutex_init(&led->lock);
+	led->client = client;
+	led->dev = &client->dev;
+	led->model_id = id->driver_data;
+	i2c_set_clientdata(client, led);
+
+	led->regmap = devm_regmap_init_i2c(client, &lp5024_regmap_config);
+	if (IS_ERR(led->regmap)) {
+		ret = PTR_ERR(led->regmap);
+		dev_err(&client->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = lp5024_probe_dt(led);
+	if (ret)
+		return ret;
+
+	ret = lp5024_init(led);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int lp5024_remove(struct i2c_client *client)
+{
+	struct lp5024 *led = i2c_get_clientdata(client);
+	int ret;
+
+	ret = regmap_update_bits(led->regmap, LP5024_DEV_CFG0,
+				 LP5024_CHIP_EN, 0);
+	if (ret) {
+		dev_err(&led->client->dev, "Failed to disable regulator\n");
+		return ret;
+	}
+
+	if (led->enable_gpio)
+		gpiod_direction_output(led->enable_gpio, 0);
+
+	if (led->regulator) {
+		ret = regulator_disable(led->regulator);
+		if (ret)
+			dev_err(&led->client->dev,
+				"Failed to disable regulator\n");
+	}
+
+	mutex_destroy(&led->lock);
+
+	return 0;
+}
+
+static const struct i2c_device_id lp5024_id[] = {
+	{ "lp5018", LP5018 },
+	{ "lp5024", LP5024 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, lp5024_id);
+
+static const struct of_device_id of_lp5024_leds_match[] = {
+	{ .compatible = "ti,lp5018", },
+	{ .compatible = "ti,lp5024", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_lp5024_leds_match);
+
+static struct i2c_driver lp5024_driver = {
+	.driver = {
+		.name	= "lp5024",
+		.of_match_table = of_lp5024_leds_match,
+	},
+	.probe		= lp5024_probe,
+	.remove		= lp5024_remove,
+	.id_table	= lp5024_id,
+};
+module_i2c_driver(lp5024_driver);
+
+MODULE_DESCRIPTION("Texas Instruments LP5024 LED driver");
+MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.20.0.rc2.7.g965798d1f2

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 16:26 ` [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver Dan Murphy
@ 2018-12-19 19:04   ` Dan Murphy
  2018-12-19 19:34   ` Pavel Machek
  2019-01-08 21:10   ` Jacek Anaszewski
  2 siblings, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2018-12-19 19:04 UTC (permalink / raw)
  To: robh+dt, jacek.anaszewski, pavel; +Cc: devicetree, linux-kernel, linux-leds

On 12/19/2018 10:26 AM, Dan Murphy wrote:
> Introduce the LP5024 and LP5018 RGB LED driver.
> The difference in these 2 parts are only in the number of
> LED outputs where the LP5024 can control 24 LEDs the LP5018
> can only control 18.
> 
> The device has the ability to group LED output into control banks
> so that multiple LED banks can be controlled with the same mixing and
> brightness.  Inversely the LEDs can also be controlled independently.
> 
> Signed-off-by: Dan Murphy <dmurphy@ti.com>
> ---
>  drivers/leds/Kconfig       |   7 +
>  drivers/leds/Makefile      |   1 +
>  drivers/leds/leds-lp5024.c | 610 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 618 insertions(+)
>  create mode 100644 drivers/leds/leds-lp5024.c
> 
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index a72f97fca57b..d306bedb00b7 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -326,6 +326,13 @@ config LEDS_LP3952
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called leds-lp3952.
>  
> +config LEDS_LP5024
> +	tristate "LED Support for TI LP5024/18 LED driver chip"
> +	depends on LEDS_CLASS && REGMAP_I2C
> +	help
> +	  If you say yes here you get support for the Texas Instruments
> +	  LP5024 and LP5018 LED driver.
> +
>  config LEDS_LP55XX_COMMON
>  	tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501"
>  	depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501
> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
> index 4c1b0054f379..60b4e4ddd3ee 100644
> --- a/drivers/leds/Makefile
> +++ b/drivers/leds/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_LEDS_GPIO_REGISTER)	+= leds-gpio-register.o
>  obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
>  obj-$(CONFIG_LEDS_LP3944)		+= leds-lp3944.o
>  obj-$(CONFIG_LEDS_LP3952)		+= leds-lp3952.o
> +obj-$(CONFIG_LEDS_LP5024)		+= leds-lp5024.o
>  obj-$(CONFIG_LEDS_LP55XX_COMMON)	+= leds-lp55xx-common.o
>  obj-$(CONFIG_LEDS_LP5521)		+= leds-lp5521.o
>  obj-$(CONFIG_LEDS_LP5523)		+= leds-lp5523.o
> diff --git a/drivers/leds/leds-lp5024.c b/drivers/leds/leds-lp5024.c
> new file mode 100644
> index 000000000000..90e8dca15609
> --- /dev/null
> +++ b/drivers/leds/leds-lp5024.c
> @@ -0,0 +1,610 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* TI LP50XX LED chip family driver
> + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
> + */
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/init.h>
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <uapi/linux/uleds.h>
> +
> +#define LP5024_DEV_CFG0		0x00
> +#define LP5024_DEV_CFG1		0x01
> +#define LP5024_LED_CFG0		0x02

I have 2 more devices that are the same as this one the LP5036/5030.

The major difference is the register map and some of the register offsets.
As well as enabling the control bank for the extra LEDs.

The delta starts here as the new devices add LED_CFG1 at 0x03 and then at LED7_BRT
there are another 4 registers and then for the OUTX_CLR there are 12 more registers.

So this pushes the RESET register way out there.

So how should I handle this?

I kicked around creating a new driver with the register and offset differences called the LP5036.

Or is there some example on how to plug those devices in as well with a different reg map?
I think a framework is over kill.

Dan

> +#define LP5024_BNK_BRT		0x03
> +#define LP5024_BNKA_CLR		0x04
> +#define LP5024_BNKB_CLR		0x05
> +#define LP5024_BNKC_CLR		0x06
> +#define LP5024_LED0_BRT		0x07
> +#define LP5024_LED1_BRT		0x08
> +#define LP5024_LED2_BRT		0x09
> +#define LP5024_LED3_BRT		0x0a
> +#define LP5024_LED4_BRT		0x0b
> +#define LP5024_LED5_BRT		0x0c
> +#define LP5024_LED6_BRT		0x0d
> +#define LP5024_LED7_BRT		0x0e
> +
> +#define LP5024_OUT0_CLR		0x0f
> +#define LP5024_OUT1_CLR		0x10
> +#define LP5024_OUT2_CLR		0x11
> +#define LP5024_OUT3_CLR		0x12
> +#define LP5024_OUT4_CLR		0x13
> +#define LP5024_OUT5_CLR		0x14
> +#define LP5024_OUT6_CLR		0x15
> +#define LP5024_OUT7_CLR		0x16
> +#define LP5024_OUT8_CLR		0x17
> +#define LP5024_OUT9_CLR		0x18
> +#define LP5024_OUT10_CLR	0x19
> +#define LP5024_OUT11_CLR	0x1a
> +#define LP5024_OUT12_CLR	0x1b
> +#define LP5024_OUT13_CLR	0x1c
> +#define LP5024_OUT14_CLR	0x1d
> +#define LP5024_OUT15_CLR	0x1e
> +#define LP5024_OUT16_CLR	0x1f
> +#define LP5024_OUT17_CLR	0x20
> +#define LP5024_OUT18_CLR	0x21
> +#define LP5024_OUT19_CLR	0x22
> +#define LP5024_OUT20_CLR	0x23
> +#define LP5024_OUT21_CLR	0x24
> +#define LP5024_OUT22_CLR	0x25
> +#define LP5024_OUT23_CLR	0x26
> +
> +#define LP5024_RESET		0x27
> +#define LP5024_SW_RESET		0xff
> +
> +#define LP5024_CHIP_EN		BIT(6)
> +
> +#define LP5024_CONTROL_A		0
> +#define LP5024_CONTROL_B		1
> +#define LP5024_CONTROL_C		2
> +#define LP5024_MAX_CONTROL_BANKS	3
> +
> +#define LP5018_MAX_LED_STRINGS	6
> +#define LP5024_MAX_LED_STRINGS	8
> +
> +enum lp5024_model {
> +	LP5018,
> +	LP5024,
> +};
> +
> +struct lp5024_led {
> +	u32 led_strings[LP5024_MAX_LED_STRINGS];
> +	char label[LED_MAX_NAME_SIZE];
> +	struct led_classdev led_dev;
> +	struct lp5024 *priv;
> +	int led_number;
> +	u8 ctrl_bank_enabled;
> +};
> +
> +/**
> + * struct lp5024 -
> + * @enable_gpio: Hardware enable gpio
> + * @regulator: LED supply regulator pointer
> + * @client: Pointer to the I2C client
> + * @regmap: Devices register map
> + * @dev: Pointer to the devices device struct
> + * @lock: Lock for reading/writing the device
> + * @model_id: ID of the device
> + * @leds: Array of LED strings
> + */
> +struct lp5024 {
> +	struct gpio_desc *enable_gpio;
> +	struct regulator *regulator;
> +	struct i2c_client *client;
> +	struct regmap *regmap;
> +	struct device *dev;
> +	struct mutex lock;
> +	int model_id;
> +	int max_leds;
> +	int num_of_leds;
> +
> +	/* This needs to be at the end of the struct */
> +	struct lp5024_led leds[];
> +};
> +
> +static const struct reg_default lp5024_reg_defs[] = {
> +	{LP5024_DEV_CFG0, 0x0},
> +	{LP5024_DEV_CFG1, 0x3c},
> +	{LP5024_BNK_BRT, 0xff},
> +	{LP5024_BNKA_CLR, 0x0f},
> +	{LP5024_BNKB_CLR, 0x0f},
> +	{LP5024_BNKC_CLR, 0x0f},
> +	{LP5024_LED0_BRT, 0x0f},
> +	{LP5024_LED1_BRT, 0xff},
> +	{LP5024_LED2_BRT, 0xff},
> +	{LP5024_LED3_BRT, 0xff},
> +	{LP5024_LED4_BRT, 0xff},
> +	{LP5024_LED5_BRT, 0xff},
> +	{LP5024_LED6_BRT, 0xff},
> +	{LP5024_LED7_BRT, 0xff},
> +	{LP5024_OUT0_CLR, 0x0f},
> +	{LP5024_OUT1_CLR, 0x00},
> +	{LP5024_OUT2_CLR, 0x00},
> +	{LP5024_OUT3_CLR, 0x00},
> +	{LP5024_OUT4_CLR, 0x00},
> +	{LP5024_OUT5_CLR, 0x00},
> +	{LP5024_OUT6_CLR, 0x00},
> +	{LP5024_OUT7_CLR, 0x00},
> +	{LP5024_OUT8_CLR, 0x00},
> +	{LP5024_OUT9_CLR, 0x00},
> +	{LP5024_OUT10_CLR, 0x00},
> +	{LP5024_OUT11_CLR, 0x00},
> +	{LP5024_OUT12_CLR, 0x00},
> +	{LP5024_OUT13_CLR, 0x00},
> +	{LP5024_OUT14_CLR, 0x00},
> +	{LP5024_OUT15_CLR, 0x00},
> +	{LP5024_OUT16_CLR, 0x00},
> +	{LP5024_OUT17_CLR, 0x00},
> +	{LP5024_OUT18_CLR, 0x00},
> +	{LP5024_OUT19_CLR, 0x00},
> +	{LP5024_OUT20_CLR, 0x00},
> +	{LP5024_OUT21_CLR, 0x00},
> +	{LP5024_OUT22_CLR, 0x00},
> +	{LP5024_OUT23_CLR, 0x00},
> +	{LP5024_RESET, 0x00}
> +};
> +
> +static const struct regmap_config lp5024_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +
> +	.max_register = LP5024_RESET,
> +	.reg_defaults = lp5024_reg_defs,
> +	.num_reg_defaults = ARRAY_SIZE(lp5024_reg_defs),
> +	.cache_type = REGCACHE_RBTREE,
> +};
> +
> +static int lp5024_set_color_mix(struct lp5024_led *led, u8 color_reg,
> +				u8 color_val)
> +{
> +	return regmap_write(led->priv->regmap, color_reg, color_val);
> +}
> +
> +
> +static ssize_t ctrl_bank_a_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	lp5024_set_color_mix(led, LP5024_BNKA_CLR, mix_value);
> +
> +	return size;
> +}
> +static ssize_t ctrl_bank_b_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	lp5024_set_color_mix(led, LP5024_BNKB_CLR, mix_value);
> +
> +	return size;
> +}
> +static ssize_t ctrl_bank_c_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	lp5024_set_color_mix(led, LP5024_BNKC_CLR, mix_value);
> +
> +	return size;
> +}
> +
> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
> +
> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
> +	&dev_attr_ctrl_bank_a_mix.attr,
> +	&dev_attr_ctrl_bank_b_mix.attr,
> +	&dev_attr_ctrl_bank_c_mix.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
> +
> +static ssize_t led3_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	u8 reg_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	reg_value = (led->led_number * 3) + LP5024_OUT2_CLR;
> +
> +	lp5024_set_color_mix(led, reg_value, mix_value);
> +
> +	return size;
> +}
> +
> +static ssize_t led2_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	u8 reg_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	reg_value = (led->led_number * 3) + LP5024_OUT1_CLR;
> +
> +	lp5024_set_color_mix(led, reg_value, mix_value);
> +
> +	return size;
> +}
> +
> +static ssize_t led1_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	u8 reg_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	reg_value = (led->led_number * 3) + LP5024_OUT0_CLR;
> +
> +	lp5024_set_color_mix(led, reg_value, mix_value);
> +
> +	return size;
> +}
> +
> +static DEVICE_ATTR_WO(led1_mix);
> +static DEVICE_ATTR_WO(led2_mix);
> +static DEVICE_ATTR_WO(led3_mix);
> +
> +static struct attribute *lp5024_led_independent_attrs[] = {
> +	&dev_attr_led1_mix.attr,
> +	&dev_attr_led2_mix.attr,
> +	&dev_attr_led3_mix.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(lp5024_led_independent);
> +
> +static int lp5024_brightness_set(struct led_classdev *led_cdev,
> +				enum led_brightness brt_val)
> +{
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	int ret = 0;
> +	u8 reg_val;
> +
> +	mutex_lock(&led->priv->lock);
> +
> +	if (led->ctrl_bank_enabled)
> +		reg_val = LP5024_BNK_BRT;
> +	else
> +		reg_val = led->led_number + LP5024_LED0_BRT;
> +
> +	ret = regmap_write(led->priv->regmap, reg_val, brt_val);
> +
> +	mutex_unlock(&led->priv->lock);
> +
> +	return ret;
> +}
> +
> +static enum led_brightness lp5024_brightness_get(struct led_classdev *led_cdev)
> +{
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	unsigned int brt_val;
> +	u8 reg_val;
> +	int ret;
> +
> +	mutex_lock(&led->priv->lock);
> +
> +	if (led->ctrl_bank_enabled)
> +		reg_val = LP5024_BNK_BRT;
> +	else
> +		reg_val = led->led_number + LP5024_LED0_BRT;
> +
> +	ret = regmap_read(led->priv->regmap, reg_val, &brt_val);
> +
> +	mutex_unlock(&led->priv->lock);
> +
> +	return brt_val;
> +}
> +
> +static int lp5024_set_led_values(struct lp5024 *priv)
> +{
> +	struct lp5024_led *led;
> +	int i, j;
> +	u8 led_ctrl_enable = 0;
> +
> +	for (i = 0; i <= priv->num_of_leds; i++) {
> +		led = &priv->leds[i];
> +		if (led->ctrl_bank_enabled) {
> +			for (j = 0; j <= LP5024_MAX_LED_STRINGS - 1; j++)
> +				led_ctrl_enable |= (1 << led->led_strings[j]);
> +		}
> +	}
> +
> +	regmap_write(priv->regmap, LP5024_LED_CFG0, led_ctrl_enable);
> +
> +	return 0;
> +}
> +
> +static int lp5024_init(struct lp5024 *priv)
> +{
> +	int ret;
> +
> +	if (priv->enable_gpio) {
> +		gpiod_direction_output(priv->enable_gpio, 1);
> +	} else {
> +		ret = regmap_write(priv->regmap, LP5024_RESET, LP5024_SW_RESET);
> +		if (ret) {
> +			dev_err(&priv->client->dev,
> +				"Cannot reset the device\n");
> +			goto out;
> +		}
> +	}
> +
> +	ret = lp5024_set_led_values(priv);
> +	if (ret)
> +		dev_err(&priv->client->dev, "Setting the CRTL bank failed\n");
> +
> +	ret = regmap_write(priv->regmap, LP5024_DEV_CFG0, LP5024_CHIP_EN);
> +	if (ret) {
> +		dev_err(&priv->client->dev, "Cannot write ctrl enable\n");
> +		goto out;
> +	}
> +out:
> +	return ret;
> +}
> +
> +static int lp5024_probe_dt(struct lp5024 *priv)
> +{
> +	struct fwnode_handle *child = NULL;
> +	struct lp5024_led *led;
> +	const char *name;
> +	int led_number;
> +	size_t i = 0;
> +	int ret;
> +
> +	priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
> +						   "enable", GPIOD_OUT_LOW);
> +	if (IS_ERR(priv->enable_gpio)) {
> +		ret = PTR_ERR(priv->enable_gpio);
> +		dev_err(&priv->client->dev, "Failed to get enable gpio: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	priv->regulator = devm_regulator_get(&priv->client->dev, "vled");
> +	if (IS_ERR(priv->regulator))
> +		priv->regulator = NULL;
> +
> +	if (priv->model_id == LP5018)
> +		priv->max_leds = LP5018_MAX_LED_STRINGS;
> +	else
> +		priv->max_leds = LP5024_MAX_LED_STRINGS;
> +
> +	device_for_each_child_node(&priv->client->dev, child) {
> +		led = &priv->leds[i];
> +
> +		if (fwnode_property_present(child, "ti,control-bank"))
> +			led->ctrl_bank_enabled = 1;
> +		else
> +			led->ctrl_bank_enabled = 0;
> +
> +		if (led->ctrl_bank_enabled) {
> +			ret = fwnode_property_read_u32_array(child,
> +							     "led-sources",
> +							     NULL, 0);
> +			ret = fwnode_property_read_u32_array(child,
> +							     "led-sources",
> +							     led->led_strings,
> +							     ret);
> +
> +			led->led_number = led->led_strings[0];
> +
> +		} else {
> +			ret = fwnode_property_read_u32(child, "led-sources",
> +					       &led_number);
> +
> +			led->led_number = led_number;
> +		}
> +		if (ret) {
> +			dev_err(&priv->client->dev,
> +				"led-sources property missing\n");
> +			fwnode_handle_put(child);
> +			goto child_out;
> +		}
> +
> +		if (led_number > priv->max_leds) {
> +			dev_err(&priv->client->dev,
> +				"led-sources property is invalid\n");
> +			ret = -EINVAL;
> +			fwnode_handle_put(child);
> +			goto child_out;
> +		}
> +
> +		ret = fwnode_property_read_string(child, "label", &name);
> +		if (ret)
> +			snprintf(led->label, sizeof(led->label),
> +				"%s::", priv->client->name);
> +		else
> +			snprintf(led->label, sizeof(led->label),
> +				 "%s:%s", priv->client->name, name);
> +
> +		fwnode_property_read_string(child, "linux,default-trigger",
> +				    &led->led_dev.default_trigger);
> +
> +		led->priv = priv;
> +		led->led_dev.name = led->label;
> +		led->led_dev.max_brightness = 255;
> +		led->led_dev.brightness_set_blocking = lp5024_brightness_set;
> +		led->led_dev.brightness_get = lp5024_brightness_get;
> +
> +		if (led->ctrl_bank_enabled)
> +			led->led_dev.groups = lp5024_ctrl_bank_groups;
> +		else
> +			led->led_dev.groups = lp5024_led_independent_groups;
> +
> +		ret = devm_led_classdev_register(&priv->client->dev,
> +						 &led->led_dev);
> +		if (ret) {
> +			dev_err(&priv->client->dev, "led register err: %d\n",
> +				ret);
> +			fwnode_handle_put(child);
> +			goto child_out;
> +		}
> +		i++;
> +	}
> +	priv->num_of_leds = i;
> +
> +child_out:
> +	return ret;
> +}
> +
> +static int lp5024_probe(struct i2c_client *client,
> +			const struct i2c_device_id *id)
> +{
> +	struct lp5024 *led;
> +	int count;
> +	int ret;
> +
> +	count = device_get_child_node_count(&client->dev);
> +	if (!count) {
> +		dev_err(&client->dev, "LEDs are not defined in device tree!");
> +		return -ENODEV;
> +	}
> +
> +	led = devm_kzalloc(&client->dev, struct_size(led, leds, count),
> +			   GFP_KERNEL);
> +	if (!led)
> +		return -ENOMEM;
> +
> +	mutex_init(&led->lock);
> +	led->client = client;
> +	led->dev = &client->dev;
> +	led->model_id = id->driver_data;
> +	i2c_set_clientdata(client, led);
> +
> +	led->regmap = devm_regmap_init_i2c(client, &lp5024_regmap_config);
> +	if (IS_ERR(led->regmap)) {
> +		ret = PTR_ERR(led->regmap);
> +		dev_err(&client->dev, "Failed to allocate register map: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	ret = lp5024_probe_dt(led);
> +	if (ret)
> +		return ret;
> +
> +	ret = lp5024_init(led);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int lp5024_remove(struct i2c_client *client)
> +{
> +	struct lp5024 *led = i2c_get_clientdata(client);
> +	int ret;
> +
> +	ret = regmap_update_bits(led->regmap, LP5024_DEV_CFG0,
> +				 LP5024_CHIP_EN, 0);
> +	if (ret) {
> +		dev_err(&led->client->dev, "Failed to disable regulator\n");
> +		return ret;
> +	}
> +
> +	if (led->enable_gpio)
> +		gpiod_direction_output(led->enable_gpio, 0);
> +
> +	if (led->regulator) {
> +		ret = regulator_disable(led->regulator);
> +		if (ret)
> +			dev_err(&led->client->dev,
> +				"Failed to disable regulator\n");
> +	}
> +
> +	mutex_destroy(&led->lock);
> +
> +	return 0;
> +}
> +
> +static const struct i2c_device_id lp5024_id[] = {
> +	{ "lp5018", LP5018 },
> +	{ "lp5024", LP5024 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, lp5024_id);
> +
> +static const struct of_device_id of_lp5024_leds_match[] = {
> +	{ .compatible = "ti,lp5018", },
> +	{ .compatible = "ti,lp5024", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, of_lp5024_leds_match);
> +
> +static struct i2c_driver lp5024_driver = {
> +	.driver = {
> +		.name	= "lp5024",
> +		.of_match_table = of_lp5024_leds_match,
> +	},
> +	.probe		= lp5024_probe,
> +	.remove		= lp5024_remove,
> +	.id_table	= lp5024_id,
> +};
> +module_i2c_driver(lp5024_driver);
> +
> +MODULE_DESCRIPTION("Texas Instruments LP5024 LED driver");
> +MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
> +MODULE_LICENSE("GPL v2");
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 16:26 ` [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver Dan Murphy
  2018-12-19 19:04   ` Dan Murphy
@ 2018-12-19 19:34   ` Pavel Machek
  2018-12-19 19:41     ` Dan Murphy
  2019-01-08 21:10   ` Jacek Anaszewski
  2 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2018-12-19 19:34 UTC (permalink / raw)
  To: Dan Murphy
  Cc: robh+dt, jacek.anaszewski, devicetree, linux-kernel, linux-leds

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

Hi!

> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
> +
> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
> +	&dev_attr_ctrl_bank_a_mix.attr,
> +	&dev_attr_ctrl_bank_b_mix.attr,
> +	&dev_attr_ctrl_bank_c_mix.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);

...
> +
> +static DEVICE_ATTR_WO(led1_mix);
> +static DEVICE_ATTR_WO(led2_mix);
> +static DEVICE_ATTR_WO(led3_mix);
> +
> +static struct attribute *lp5024_led_independent_attrs[] = {
> +	&dev_attr_led1_mix.attr,
> +	&dev_attr_led2_mix.attr,
> +	&dev_attr_led3_mix.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(lp5024_led_independent);

Ok, so you are adding new sysfs files. Are they _really_ neccessary?
We'd like to have uniform interfaces for the leds.

If they are neccessary, we need documentation for them.

Thanks,
									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 19:34   ` Pavel Machek
@ 2018-12-19 19:41     ` Dan Murphy
  2018-12-19 20:10       ` Pavel Machek
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2018-12-19 19:41 UTC (permalink / raw)
  To: Pavel Machek
  Cc: robh+dt, jacek.anaszewski, devicetree, linux-kernel, linux-leds

Pavel

Thanks for the review.

On 12/19/2018 01:34 PM, Pavel Machek wrote:
> Hi!
> 
>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
>> +
>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>> +	&dev_attr_ctrl_bank_a_mix.attr,
>> +	&dev_attr_ctrl_bank_b_mix.attr,
>> +	&dev_attr_ctrl_bank_c_mix.attr,
>> +	NULL
>> +};
>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
> 
> ...
>> +
>> +static DEVICE_ATTR_WO(led1_mix);
>> +static DEVICE_ATTR_WO(led2_mix);
>> +static DEVICE_ATTR_WO(led3_mix);
>> +
>> +static struct attribute *lp5024_led_independent_attrs[] = {
>> +	&dev_attr_led1_mix.attr,
>> +	&dev_attr_led2_mix.attr,
>> +	&dev_attr_led3_mix.attr,
>> +	NULL
>> +};
>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
> 
> Ok, so you are adding new sysfs files. Are they _really_ neccessary?
> We'd like to have uniform interfaces for the leds.

Yes I am adding these for this driver.
They adjust the individual brightness of each LED connected (what the HW guys called mixing).

The standard brightness sysfs adjusts all 3 LEDs simultaneously so that all 3 LEDs brightness are
uniform.

I did not think these belonged in the dt as they should be user space configurable

> 
> If they are neccessary, we need documentation for them.

Sure I have no problem documenting them but where do I do that?
I am assuming Documentation/leds/leds-lp5024.txt

This looks to be where Milo did this before.

Dan

> 
> Thanks,
> 									Pavel
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 19:41     ` Dan Murphy
@ 2018-12-19 20:10       ` Pavel Machek
  2018-12-19 20:41         ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2018-12-19 20:10 UTC (permalink / raw)
  To: Dan Murphy
  Cc: robh+dt, jacek.anaszewski, devicetree, linux-kernel, linux-leds

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

On Wed 2018-12-19 13:41:18, Dan Murphy wrote:
> Pavel
> 
> Thanks for the review.
> 
> On 12/19/2018 01:34 PM, Pavel Machek wrote:
> > Hi!
> > 
> >> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
> >> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
> >> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
> >> +
> >> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
> >> +	&dev_attr_ctrl_bank_a_mix.attr,
> >> +	&dev_attr_ctrl_bank_b_mix.attr,
> >> +	&dev_attr_ctrl_bank_c_mix.attr,
> >> +	NULL
> >> +};
> >> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
> > 
> > ...
> >> +
> >> +static DEVICE_ATTR_WO(led1_mix);
> >> +static DEVICE_ATTR_WO(led2_mix);
> >> +static DEVICE_ATTR_WO(led3_mix);
> >> +
> >> +static struct attribute *lp5024_led_independent_attrs[] = {
> >> +	&dev_attr_led1_mix.attr,
> >> +	&dev_attr_led2_mix.attr,
> >> +	&dev_attr_led3_mix.attr,
> >> +	NULL
> >> +};
> >> +ATTRIBUTE_GROUPS(lp5024_led_independent);
> > 
> > Ok, so you are adding new sysfs files. Are they _really_ neccessary?
> > We'd like to have uniform interfaces for the leds.
> 
> Yes I am adding these for this driver.
> They adjust the individual brightness of each LED connected (what the HW guys called mixing).
> 
> The standard brightness sysfs adjusts all 3 LEDs simultaneously so that all 3 LEDs brightness are
> uniform.

1 LED, 1 brightness file... that's what we do. Why should this one be different?

> I did not think these belonged in the dt as they should be user space configurable
> 
> > 
> > If they are neccessary, we need documentation for them.
> 
> Sure I have no problem documenting them but where do I do that?
> I am assuming Documentation/leds/leds-lp5024.txt

Documentation/abi/...

									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 20:10       ` Pavel Machek
@ 2018-12-19 20:41         ` Dan Murphy
  2018-12-19 21:36           ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2018-12-19 20:41 UTC (permalink / raw)
  To: Pavel Machek
  Cc: robh+dt, jacek.anaszewski, devicetree, linux-kernel, linux-leds

Pavel

On 12/19/2018 02:10 PM, Pavel Machek wrote:
> On Wed 2018-12-19 13:41:18, Dan Murphy wrote:
>> Pavel
>>
>> Thanks for the review.
>>
>> On 12/19/2018 01:34 PM, Pavel Machek wrote:
>>> Hi!
>>>
>>>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>>>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>>>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
>>>> +
>>>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>>>> +	&dev_attr_ctrl_bank_a_mix.attr,
>>>> +	&dev_attr_ctrl_bank_b_mix.attr,
>>>> +	&dev_attr_ctrl_bank_c_mix.attr,
>>>> +	NULL
>>>> +};
>>>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
>>>
>>> ...
>>>> +
>>>> +static DEVICE_ATTR_WO(led1_mix);
>>>> +static DEVICE_ATTR_WO(led2_mix);
>>>> +static DEVICE_ATTR_WO(led3_mix);
>>>> +
>>>> +static struct attribute *lp5024_led_independent_attrs[] = {
>>>> +	&dev_attr_led1_mix.attr,
>>>> +	&dev_attr_led2_mix.attr,
>>>> +	&dev_attr_led3_mix.attr,
>>>> +	NULL
>>>> +};
>>>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
>>>
>>> Ok, so you are adding new sysfs files. Are they _really_ neccessary?
>>> We'd like to have uniform interfaces for the leds.
>>
>> Yes I am adding these for this driver.
>> They adjust the individual brightness of each LED connected (what the HW guys called mixing).
>>
>> The standard brightness sysfs adjusts all 3 LEDs simultaneously so that all 3 LEDs brightness are
>> uniform.
> 
> 1 LED, 1 brightness file... that's what we do. Why should this one be different?
> 

Yes I understand this and 1 DT child node per LED out but...

This device has a single register to control 3 LEDs brightness as a group and individual brightness
registers to control the LEDs independently to mix the LEDs to a specific color.

There needs to be a way to control both so that developers can mix and adjust the individual RGB and
then control the brightness of the group during run time without touching the "mixing" value.

I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
Or with the LP5036 that would have 36 LED nodes.

Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.

Dan


>> I did not think these belonged in the dt as they should be user space configurable
>>
>>>
>>> If they are neccessary, we need documentation for them.
>>
>> Sure I have no problem documenting them but where do I do that?
>> I am assuming Documentation/leds/leds-lp5024.txt
> 
> Documentation/abi/...
> 
> 									Pavel
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 20:41         ` Dan Murphy
@ 2018-12-19 21:36           ` Jacek Anaszewski
  2018-12-19 21:50             ` Dan Murphy
  2018-12-19 22:03             ` Pavel Machek
  0 siblings, 2 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2018-12-19 21:36 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek; +Cc: robh+dt, devicetree, linux-kernel, linux-leds

Hi Dan and Pavel,

On 12/19/18 9:41 PM, Dan Murphy wrote:
> Pavel
> 
> On 12/19/2018 02:10 PM, Pavel Machek wrote:
>> On Wed 2018-12-19 13:41:18, Dan Murphy wrote:
>>> Pavel
>>>
>>> Thanks for the review.
>>>
>>> On 12/19/2018 01:34 PM, Pavel Machek wrote:
>>>> Hi!
>>>>
>>>>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>>>>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>>>>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
>>>>> +
>>>>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>>>>> +	&dev_attr_ctrl_bank_a_mix.attr,
>>>>> +	&dev_attr_ctrl_bank_b_mix.attr,
>>>>> +	&dev_attr_ctrl_bank_c_mix.attr,
>>>>> +	NULL
>>>>> +};
>>>>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
>>>>
>>>> ...
>>>>> +
>>>>> +static DEVICE_ATTR_WO(led1_mix);
>>>>> +static DEVICE_ATTR_WO(led2_mix);
>>>>> +static DEVICE_ATTR_WO(led3_mix);
>>>>> +
>>>>> +static struct attribute *lp5024_led_independent_attrs[] = {
>>>>> +	&dev_attr_led1_mix.attr,
>>>>> +	&dev_attr_led2_mix.attr,
>>>>> +	&dev_attr_led3_mix.attr,
>>>>> +	NULL
>>>>> +};
>>>>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
>>>>
>>>> Ok, so you are adding new sysfs files. Are they _really_ neccessary?
>>>> We'd like to have uniform interfaces for the leds.
>>>
>>> Yes I am adding these for this driver.
>>> They adjust the individual brightness of each LED connected (what the HW guys called mixing).
>>>
>>> The standard brightness sysfs adjusts all 3 LEDs simultaneously so that all 3 LEDs brightness are
>>> uniform.
>>
>> 1 LED, 1 brightness file... that's what we do. Why should this one be different?
>>
> 
> Yes I understand this and 1 DT child node per LED out but...
> 
> This device has a single register to control 3 LEDs brightness as a group and individual brightness
> registers to control the LEDs independently to mix the LEDs to a specific color.
> 
> There needs to be a way to control both so that developers can mix and adjust the individual RGB and
> then control the brightness of the group during run time without touching the "mixing" value.
> 
> I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
> Or with the LP5036 that would have 36 LED nodes.
> 
> Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.

Some time ago we had discussion with Vesa Jääskeläinen about possible
approaches to RGB LEDs [0]. What seemed to be the most suitable
variation of the discussed out-of-tree approach was the "color" property
and array of color triplets defined in Device Tree per each color.

Please refer to [0] for the details.

[0] https://lkml.org/lkml/2018/11/9/938

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 21:36           ` Jacek Anaszewski
@ 2018-12-19 21:50             ` Dan Murphy
  2018-12-20 12:40               ` Vesa Jääskeläinen
  2018-12-20 20:31               ` Jacek Anaszewski
  2018-12-19 22:03             ` Pavel Machek
  1 sibling, 2 replies; 106+ messages in thread
From: Dan Murphy @ 2018-12-19 21:50 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 12/19/2018 03:36 PM, Jacek Anaszewski wrote:
> Hi Dan and Pavel,
> 
> On 12/19/18 9:41 PM, Dan Murphy wrote:
>> Pavel
>>
>> On 12/19/2018 02:10 PM, Pavel Machek wrote:
>>> On Wed 2018-12-19 13:41:18, Dan Murphy wrote:
>>>> Pavel
>>>>
>>>> Thanks for the review.
>>>>
>>>> On 12/19/2018 01:34 PM, Pavel Machek wrote:
>>>>> Hi!
>>>>>
>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
>>>>>> +
>>>>>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>>>>>> +    &dev_attr_ctrl_bank_a_mix.attr,
>>>>>> +    &dev_attr_ctrl_bank_b_mix.attr,
>>>>>> +    &dev_attr_ctrl_bank_c_mix.attr,
>>>>>> +    NULL
>>>>>> +};
>>>>>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
>>>>>
>>>>> ...
>>>>>> +
>>>>>> +static DEVICE_ATTR_WO(led1_mix);
>>>>>> +static DEVICE_ATTR_WO(led2_mix);
>>>>>> +static DEVICE_ATTR_WO(led3_mix);
>>>>>> +
>>>>>> +static struct attribute *lp5024_led_independent_attrs[] = {
>>>>>> +    &dev_attr_led1_mix.attr,
>>>>>> +    &dev_attr_led2_mix.attr,
>>>>>> +    &dev_attr_led3_mix.attr,
>>>>>> +    NULL
>>>>>> +};
>>>>>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
>>>>>
>>>>> Ok, so you are adding new sysfs files. Are they _really_ neccessary?
>>>>> We'd like to have uniform interfaces for the leds.
>>>>
>>>> Yes I am adding these for this driver.
>>>> They adjust the individual brightness of each LED connected (what the HW guys called mixing).
>>>>
>>>> The standard brightness sysfs adjusts all 3 LEDs simultaneously so that all 3 LEDs brightness are
>>>> uniform.
>>>
>>> 1 LED, 1 brightness file... that's what we do. Why should this one be different?
>>>
>>
>> Yes I understand this and 1 DT child node per LED out but...
>>
>> This device has a single register to control 3 LEDs brightness as a group and individual brightness
>> registers to control the LEDs independently to mix the LEDs to a specific color.
>>
>> There needs to be a way to control both so that developers can mix and adjust the individual RGB and
>> then control the brightness of the group during run time without touching the "mixing" value.
>>
>> I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
>> Or with the LP5036 that would have 36 LED nodes.
>>
>> Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.
> 
> Some time ago we had discussion with Vesa Jääskeläinen about possible
> approaches to RGB LEDs [0]. What seemed to be the most suitable
> variation of the discussed out-of-tree approach was the "color" property
> and array of color triplets defined in Device Tree per each color.
> 

Why does Device tree define the color?

Rob indicated that Device tree is supposed to define the hardware.
This thread seems to be defining the operation.

Shouldn't the color be done via user space and not dt?

Especially if they want to change the color real time?

Dan

> Please refer to [0] for the details.
> 
> [0] https://lkml.org/lkml/2018/11/9/938
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 21:36           ` Jacek Anaszewski
  2018-12-19 21:50             ` Dan Murphy
@ 2018-12-19 22:03             ` Pavel Machek
  2018-12-19 22:08               ` Dan Murphy
  1 sibling, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2018-12-19 22:03 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

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

Hi!

> >I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
> >Or with the LP5036 that would have 36 LED nodes.
> >
> >Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.
> 
> Some time ago we had discussion with Vesa Jääskeläinen about possible
> approaches to RGB LEDs [0]. What seemed to be the most suitable
> variation of the discussed out-of-tree approach was the "color" property
> and array of color triplets defined in Device Tree per each color.
> 
> Please refer to [0] for the details.
> 
> [0] https://lkml.org/lkml/2018/11/9/938

Yes, plus I also have the set of HSV patches somewhere... and they
work, but I found out that HSV->RGB conversion results in loss of precision.

We may want to do something like that.

But we need to do it once, in a driver core. We obviously don't want
each driver having different version of RGB support.

Best regards,
									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 22:03             ` Pavel Machek
@ 2018-12-19 22:08               ` Dan Murphy
  2018-12-19 22:27                 ` Pavel Machek
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2018-12-19 22:08 UTC (permalink / raw)
  To: Pavel Machek, Jacek Anaszewski
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 12/19/2018 04:03 PM, Pavel Machek wrote:
> Hi!
> 
>>> I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
>>> Or with the LP5036 that would have 36 LED nodes.
>>>
>>> Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.
>>
>> Some time ago we had discussion with Vesa Jääskeläinen about possible
>> approaches to RGB LEDs [0]. What seemed to be the most suitable
>> variation of the discussed out-of-tree approach was the "color" property
>> and array of color triplets defined in Device Tree per each color.
>>
>> Please refer to [0] for the details.
>>
>> [0] https://lkml.org/lkml/2018/11/9/938
> 
> Yes, plus I also have the set of HSV patches somewhere... and they
> work, but I found out that HSV->RGB conversion results in loss of precision.
> 
> We may want to do something like that.
> 
> But we need to do it once, in a driver core. We obviously don't want
> each driver having different version of RGB support.

True.  But the RGB driver really should not be defining the color palette.

Maybe a "color capability" reported to user space so that the user space can make the decision.

It can report

For GPIO or constant current situations
static red
static blue
static green 

For adjustable configurations it can report:
variable red
variable blue
variable green

or even simpler "static" or "dynamic" as a return to report the RGB configuration.
The LED driver would just need to set the variable.

Dan

> 
> Best regards,
> 									Pavel
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 22:08               ` Dan Murphy
@ 2018-12-19 22:27                 ` Pavel Machek
  2018-12-20  1:31                   ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2018-12-19 22:27 UTC (permalink / raw)
  To: Dan Murphy; +Cc: jacek.anaszewski, linux-leds, kernel list

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

Hi!

[cc list trimmed]

> >>> I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
> >>> Or with the LP5036 that would have 36 LED nodes.
> >>>
> >>> Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.
> >>
> >> Some time ago we had discussion with Vesa Jääskeläinen about possible
> >> approaches to RGB LEDs [0]. What seemed to be the most suitable
> >> variation of the discussed out-of-tree approach was the "color" property
> >> and array of color triplets defined in Device Tree per each color.
> >>
> >> Please refer to [0] for the details.
> >>
> >> [0] https://lkml.org/lkml/2018/11/9/938
> > 
> > Yes, plus I also have the set of HSV patches somewhere... and they
> > work, but I found out that HSV->RGB conversion results in loss of precision.
> > 
> > We may want to do something like that.
> > 
> > But we need to do it once, in a driver core. We obviously don't want
> > each driver having different version of RGB support.
> 
> True.  But the RGB driver really should not be defining the color palette.
> 
> Maybe a "color capability" reported to user space so that the user space can make the decision.
> 
> It can report
> 
> For GPIO or constant current situations
> static red
> static blue
> static green 
> 
> For adjustable configurations it can report:
> variable red
> variable blue
> variable green
> 
> or even simpler "static" or "dynamic" as a return to report the RGB configuration.
> The LED driver would just need to set the variable.

I'm not sure what static/variable is.

I have RGB leds here that can set any channel to 0-255, at
runtime. They seem to be quite common at phones.

Anyway, if your 36 channels can be set independently, I believe you
just want them to export as 36 LEDs.

Thanks,
									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 22:27                 ` Pavel Machek
@ 2018-12-20  1:31                   ` Dan Murphy
  2018-12-20  9:06                     ` Pavel Machek
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2018-12-20  1:31 UTC (permalink / raw)
  To: Pavel Machek; +Cc: jacek.anaszewski, linux-leds, kernel list

Pavel

Thanks for trimming.

On 12/19/2018 04:27 PM, Pavel Machek wrote:
> Hi!
> 
> [cc list trimmed]
> 
>>>>> I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
>>>>> Or with the LP5036 that would have 36 LED nodes.
>>>>>
>>>>> Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.
>>>>
>>>> Some time ago we had discussion with Vesa Jääskeläinen about possible
>>>> approaches to RGB LEDs [0]. What seemed to be the most suitable
>>>> variation of the discussed out-of-tree approach was the "color" property
>>>> and array of color triplets defined in Device Tree per each color.
>>>>
>>>> Please refer to [0] for the details.
>>>>
>>>> [0] https://lkml.org/lkml/2018/11/9/938
>>>
>>> Yes, plus I also have the set of HSV patches somewhere... and they
>>> work, but I found out that HSV->RGB conversion results in loss of precision.
>>>
>>> We may want to do something like that.
>>>
>>> But we need to do it once, in a driver core. We obviously don't want
>>> each driver having different version of RGB support.
>>
>> True.  But the RGB driver really should not be defining the color palette.
>>
>> Maybe a "color capability" reported to user space so that the user space can make the decision.
>>
>> It can report
>>
>> For GPIO or constant current situations
>> static red
>> static blue
>> static green 
>>
>> For adjustable configurations it can report:
>> variable red
>> variable blue
>> variable green
>>
>> or even simpler "static" or "dynamic" as a return to report the RGB configuration.
>> The LED driver would just need to set the variable.
> 
> I'm not sure what static/variable is.

My suggestion is really based in opinion.  It is my opinion that the user space sets the policy
of the RGB.  The DT nor the driver should limit the capability of what the user would want to do.

But instead should let the user know what the driver and HW can do.  It seems that the suggestion made in the
email thread [0] https://lkml.org/lkml/2018/11/9/938 limits that capability via the DT by defining a specific color.

If I have a configurable current RGB combo then the palette is endless.  But in a GPIO fixed current situation the palette is
limited.  So I don't think I agree with the DT side of it.

There needs to be a way that the kernel can indicate to the user space "heres what I can do you need to let me know".
As each kernel driver just needs to interact with the HW and not set policy.

> 
> I have RGB leds here that can set any channel to 0-255, at
> runtime. They seem to be quite common at phones.

Yes I agree.  Android specifically likes to set these values in the lighting HAL.

But alternatively once the color is set the brightness can be controlled by PWM or an ALS.

> 
> Anyway, if your 36 channels can be set independently, I believe you
> just want them to export as 36 LEDs.

I am not sure that is what the "customers" would want to have to set 36 different nodes or even declare those 36 nodes.
That is 36 independent user space to kernel space calls that are very expensive just to set a LED color and brightness.

Now that is very unrealistic that there would be 36 calls happening.  But for this part it
would cut the calls to set the brightness to the kernel in runtime after init to 1/3.  Set the color and then only one call for the brightness.

Dan

> 
> Thanks,
> 									Pavel
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-20  1:31                   ` Dan Murphy
@ 2018-12-20  9:06                     ` Pavel Machek
  2018-12-20 14:03                       ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2018-12-20  9:06 UTC (permalink / raw)
  To: Dan Murphy; +Cc: jacek.anaszewski, linux-leds, kernel list

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

Hi!

> > Anyway, if your 36 channels can be set independently, I believe you
> > just want them to export as 36 LEDs.
> 
> I am not sure that is what the "customers" would want to have to set 36 different nodes or even declare those 36 nodes.
> That is 36 independent user space to kernel space calls that are very expensive just to set a LED color and brightness.
> 

No, 36 independend calls to kernel space are not that expensive.

									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 21:50             ` Dan Murphy
@ 2018-12-20 12:40               ` Vesa Jääskeläinen
  2018-12-20 13:56                 ` Dan Murphy
  2019-01-01 13:45                 ` Vesa Jääskeläinen
  2018-12-20 20:31               ` Jacek Anaszewski
  1 sibling, 2 replies; 106+ messages in thread
From: Vesa Jääskeläinen @ 2018-12-20 12:40 UTC (permalink / raw)
  To: Dan Murphy, Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Hi All,

On 19/12/2018 23.50, Dan Murphy wrote:
> On 12/19/2018 03:36 PM, Jacek Anaszewski wrote:
>> Hi Dan and Pavel,
>> Some time ago we had discussion with Vesa Jääskeläinen about possible
>> approaches to RGB LEDs [0]. What seemed to be the most suitable
>> variation of the discussed out-of-tree approach was the "color" property
>> and array of color triplets defined in Device Tree per each color.
>>
> 
> Why does Device tree define the color?
> 
> Rob indicated that Device tree is supposed to define the hardware.
> This thread seems to be defining the operation.
> 
> Shouldn't the color be done via user space and not dt?
> 
> Especially if they want to change the color real time?
> 
> Dan
> 
>> Please refer to [0] for the details.
>>
>> [0] https://lkml.org/lkml/2018/11/9/938
>>

Idea was to define preset colors in device tree as an example when you 
are dealing with multi-color LEDs without PWM. In that case you only 
have GPIOs to control and then have a problem what does those GPIO's mean.

With preset definitions one can use color names to act as a shortcut to 
configure GPIO's to proper state for that particular color.

For more flexible setups where you have PWM or such control you have 
larger space of available colors. In this case you need to somehow 
define also meaning of those controls.

Also we may not have LED with only red, green and blue elements. There 
might in example be amber, ultraviolet, white elements.

This is where device tree is concerned. It helps us craft the logical 
definition for LED so that we can control it from user space in common way.

Now the next problem then is how does user space work then.

For multi-color LEDs it it important to change the color atomically so 
that no wrong colors are being shown as user space got interrupted when 
controlling it.

Also we have brightness setting that would be useful for PWM controlled 
LEDs.

Setting color is easy when you use preset names then you only need to 
deal with brightness value (eg. RGB -> HSV * brightness -> RGB). Of 
course here additional problem is other color elements are they then 
scaled according to brightness value?.

Setting color as "raw" values is then next problem. In order to do it 
atomically it needs to be one atomic activation and could be eg. one 
write to "color" sysfs entry with combination of all color elements and 
perhaps additionally also brightness value. Next question is then what 
is the format for such entry then? What are the value ranges? In here we 
can utilize device tree definition to help define what kind of LED we do 
have and what kind of capabilities it does have.

Additional problem risen also in discussion was non-linearity of some 
control mechanisms vs. perceived color. So there might be a need for 
curve mapping similarly what is with backlight control and that would be 
defined either in device tree and possibly in user space if there is a 
need for that. I suppose golden curve definition in device tree should 
be good enough.

Then there was additional discussion about possible animation support 
but I would leave that for future design as that would then be utilizing 
the same framework.

I suppose color space handling and that kind of stuff should be in some 
led core functionality and then raw control should be part of physical 
led driver.

I was planning to play with it during holiday season but lets see how it 
goes. Feel free to also experiment with the idea.

Thanks,
Vesa Jääskeläinen

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-20 12:40               ` Vesa Jääskeläinen
@ 2018-12-20 13:56                 ` Dan Murphy
  2019-01-01 13:45                 ` Vesa Jääskeläinen
  1 sibling, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2018-12-20 13:56 UTC (permalink / raw)
  To: Vesa Jääskeläinen, Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Vesa

On 12/20/2018 06:40 AM, Vesa Jääskeläinen wrote:
> Hi All,
> 
> On 19/12/2018 23.50, Dan Murphy wrote:
>> On 12/19/2018 03:36 PM, Jacek Anaszewski wrote:
>>> Hi Dan and Pavel,
>>> Some time ago we had discussion with Vesa Jääskeläinen about possible
>>> approaches to RGB LEDs [0]. What seemed to be the most suitable
>>> variation of the discussed out-of-tree approach was the "color" property
>>> and array of color triplets defined in Device Tree per each color.
>>>
>>
>> Why does Device tree define the color?
>>
>> Rob indicated that Device tree is supposed to define the hardware.
>> This thread seems to be defining the operation.
>>
>> Shouldn't the color be done via user space and not dt?
>>
>> Especially if they want to change the color real time?
>>
>> Dan
>>
>>> Please refer to [0] for the details.
>>>
>>> [0] https://lkml.org/lkml/2018/11/9/938
>>>
> 
> Idea was to define preset colors in device tree as an example when you are dealing with multi-color LEDs without PWM. In that case you only have GPIOs to control and then have a problem what does those GPIO's mean.
> 
> With preset definitions one can use color names to act as a shortcut to configure GPIO's to proper state for that particular color.
> 
> For more flexible setups where you have PWM or such control you have larger space of available colors. In this case you need to somehow define also meaning of those controls.
> 
> Also we may not have LED with only red, green and blue elements. There might in example be amber, ultraviolet, white elements.
> 
> This is where device tree is concerned. It helps us craft the logical definition for LED so that we can control it from user space in common way.
> 
> Now the next problem then is how does user space work then.
> 
> For multi-color LEDs it it important to change the color atomically so that no wrong colors are being shown as user space got interrupted when controlling it.
> 
> Also we have brightness setting that would be useful for PWM controlled LEDs.
> 
> Setting color is easy when you use preset names then you only need to deal with brightness value (eg. RGB -> HSV * brightness -> RGB). Of course here additional problem is other color elements are they then scaled according to brightness value?.
> 
> Setting color as "raw" values is then next problem. In order to do it atomically it needs to be one atomic activation and could be eg. one write to "color" sysfs entry with combination of all color elements and perhaps additionally also brightness value. Next question is then what is the format for such entry then? What are the value ranges? In here we can utilize device tree definition to help define what kind of LED we do have and what kind of capabilities it does have.
> 
> Additional problem risen also in discussion was non-linearity of some control mechanisms vs. perceived color. So there might be a need for curve mapping similarly what is with backlight control and that would be defined either in device tree and possibly in user space if there is a need for that. I suppose golden curve definition in device tree should be good enough.
> 
> Then there was additional discussion about possible animation support but I would leave that for future design as that would then be utilizing the same framework.
> 
> I suppose color space handling and that kind of stuff should be in some led core functionality and then raw control should be part of physical led driver.
> 
> I was planning to play with it during holiday season but lets see how it goes. Feel free to also experiment with the idea.
> 

Again I don't think device tree should be used to set color policy.
This is to restricting it may be good for GPIO fixed current RGB LEDs but for variable RGB LEDs it would be very restricting.

I believe this needs to be part of the LED framework and leave the device tree to define the HW and not define the product.

Maybe a new devm_rgb_register call that exposes the color palette and can consolidate the 3 LEDs into a single sysfs node.

Dan


> Thanks,
> Vesa Jääskeläinen


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-20  9:06                     ` Pavel Machek
@ 2018-12-20 14:03                       ` Dan Murphy
  0 siblings, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2018-12-20 14:03 UTC (permalink / raw)
  To: Pavel Machek; +Cc: jacek.anaszewski, linux-leds, kernel list

On 12/20/2018 03:06 AM, Pavel Machek wrote:
> Hi!
> 
>>> Anyway, if your 36 channels can be set independently, I believe you
>>> just want them to export as 36 LEDs.
>>
>> I am not sure that is what the "customers" would want to have to set 36 different nodes or even declare those 36 nodes.
>> That is 36 independent user space to kernel space calls that are very expensive just to set a LED color and brightness.
>>
> 
> No, 36 independend calls to kernel space are not that expensive.

But they are time consuming.

Also note that even if I set the OUTX color mix register the LEDX brightness register controls the output intensity.

So if the brightness is 0x0 and the Mix register is 0xff then the LED is still off.

I am sticking with the driver as is.  I think this is a better representation of the part and its capability then presenting x number of
sysfs nodes that will have no affect on the LED if set until the corresponding brightness register is not set properly.

This will also keep the device tree entries down to a minimum.  The LEDx brightness register actually
controls the output and there are only 7 of these.

Dan

> 
> 									Pavel
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 21:50             ` Dan Murphy
  2018-12-20 12:40               ` Vesa Jääskeläinen
@ 2018-12-20 20:31               ` Jacek Anaszewski
  2018-12-21  7:32                 ` Jacek Anaszewski
  1 sibling, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2018-12-20 20:31 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek; +Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 12/19/18 10:50 PM, Dan Murphy wrote:
> On 12/19/2018 03:36 PM, Jacek Anaszewski wrote:
>> Hi Dan and Pavel,
>>
>> On 12/19/18 9:41 PM, Dan Murphy wrote:
>>> Pavel
>>>
>>> On 12/19/2018 02:10 PM, Pavel Machek wrote:
>>>> On Wed 2018-12-19 13:41:18, Dan Murphy wrote:
>>>>> Pavel
>>>>>
>>>>> Thanks for the review.
>>>>>
>>>>> On 12/19/2018 01:34 PM, Pavel Machek wrote:
>>>>>> Hi!
>>>>>>
>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
>>>>>>> +
>>>>>>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>>>>>>> +    &dev_attr_ctrl_bank_a_mix.attr,
>>>>>>> +    &dev_attr_ctrl_bank_b_mix.attr,
>>>>>>> +    &dev_attr_ctrl_bank_c_mix.attr,
>>>>>>> +    NULL
>>>>>>> +};
>>>>>>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
>>>>>>
>>>>>> ...
>>>>>>> +
>>>>>>> +static DEVICE_ATTR_WO(led1_mix);
>>>>>>> +static DEVICE_ATTR_WO(led2_mix);
>>>>>>> +static DEVICE_ATTR_WO(led3_mix);
>>>>>>> +
>>>>>>> +static struct attribute *lp5024_led_independent_attrs[] = {
>>>>>>> +    &dev_attr_led1_mix.attr,
>>>>>>> +    &dev_attr_led2_mix.attr,
>>>>>>> +    &dev_attr_led3_mix.attr,
>>>>>>> +    NULL
>>>>>>> +};
>>>>>>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
>>>>>>
>>>>>> Ok, so you are adding new sysfs files. Are they _really_ neccessary?
>>>>>> We'd like to have uniform interfaces for the leds.
>>>>>
>>>>> Yes I am adding these for this driver.
>>>>> They adjust the individual brightness of each LED connected (what the HW guys called mixing).
>>>>>
>>>>> The standard brightness sysfs adjusts all 3 LEDs simultaneously so that all 3 LEDs brightness are
>>>>> uniform.
>>>>
>>>> 1 LED, 1 brightness file... that's what we do. Why should this one be different?
>>>>
>>>
>>> Yes I understand this and 1 DT child node per LED out but...
>>>
>>> This device has a single register to control 3 LEDs brightness as a group and individual brightness
>>> registers to control the LEDs independently to mix the LEDs to a specific color.
>>>
>>> There needs to be a way to control both so that developers can mix and adjust the individual RGB and
>>> then control the brightness of the group during run time without touching the "mixing" value.
>>>
>>> I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
>>> Or with the LP5036 that would have 36 LED nodes.
>>>
>>> Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.
>>
>> Some time ago we had discussion with Vesa Jääskeläinen about possible
>> approaches to RGB LEDs [0]. What seemed to be the most suitable
>> variation of the discussed out-of-tree approach was the "color" property
>> and array of color triplets defined in Device Tree per each color.
>>
> 
> Why does Device tree define the color?
> 
> Rob indicated that Device tree is supposed to define the hardware.
> This thread seems to be defining the operation.

Perceived colors produced by LEDs from different manufacturers may
differ and this alone should be deemed a sufficient argument for having
board specific color definitions.

> Shouldn't the color be done via user space and not dt?

I think that we should keep the userspace interface as simple
as possible and backwards compatible with monochrome LEDs.

I also propose to avoid the introduction of a color sysfs
property in favor of creating separate LED class devices
for different "color ranges". The devices would drive the same
LED but using different preset color levels.

We don't have to expose all device knobs to the userspace,
but instead provide some predefined configurations. It would
improve user experience by keeping LED class devices simple
in use. It would be Device Tree designer's responsibility to
provide color definitions that make sense for given RGB LED
controller and RGB LED element configuration.

Registering color palette with devm_rgb_register() you proposed
is also an option, but with one LED class device per color palette
it would mean allowing for creation/destruction of LED class
devices by any user having access to given LED's sysfs interface,
which is really bad solution.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-20 20:31               ` Jacek Anaszewski
@ 2018-12-21  7:32                 ` Jacek Anaszewski
  2018-12-21 13:05                   ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2018-12-21  7:32 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek; +Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 12/20/18 9:31 PM, Jacek Anaszewski wrote:
> On 12/19/18 10:50 PM, Dan Murphy wrote:
>> On 12/19/2018 03:36 PM, Jacek Anaszewski wrote:
>>> Hi Dan and Pavel,
>>>
>>> On 12/19/18 9:41 PM, Dan Murphy wrote:
>>>> Pavel
>>>>
>>>> On 12/19/2018 02:10 PM, Pavel Machek wrote:
>>>>> On Wed 2018-12-19 13:41:18, Dan Murphy wrote:
>>>>>> Pavel
>>>>>>
>>>>>> Thanks for the review.
>>>>>>
>>>>>> On 12/19/2018 01:34 PM, Pavel Machek wrote:
>>>>>>> Hi!
>>>>>>>
>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
>>>>>>>> +
>>>>>>>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>>>>>>>> +    &dev_attr_ctrl_bank_a_mix.attr,
>>>>>>>> +    &dev_attr_ctrl_bank_b_mix.attr,
>>>>>>>> +    &dev_attr_ctrl_bank_c_mix.attr,
>>>>>>>> +    NULL
>>>>>>>> +};
>>>>>>>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
>>>>>>>
>>>>>>> ...
>>>>>>>> +
>>>>>>>> +static DEVICE_ATTR_WO(led1_mix);
>>>>>>>> +static DEVICE_ATTR_WO(led2_mix);
>>>>>>>> +static DEVICE_ATTR_WO(led3_mix);
>>>>>>>> +
>>>>>>>> +static struct attribute *lp5024_led_independent_attrs[] = {
>>>>>>>> +    &dev_attr_led1_mix.attr,
>>>>>>>> +    &dev_attr_led2_mix.attr,
>>>>>>>> +    &dev_attr_led3_mix.attr,
>>>>>>>> +    NULL
>>>>>>>> +};
>>>>>>>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
>>>>>>>
>>>>>>> Ok, so you are adding new sysfs files. Are they _really_ neccessary?
>>>>>>> We'd like to have uniform interfaces for the leds.
>>>>>>
>>>>>> Yes I am adding these for this driver.
>>>>>> They adjust the individual brightness of each LED connected (what 
>>>>>> the HW guys called mixing).
>>>>>>
>>>>>> The standard brightness sysfs adjusts all 3 LEDs simultaneously so 
>>>>>> that all 3 LEDs brightness are
>>>>>> uniform.
>>>>>
>>>>> 1 LED, 1 brightness file... that's what we do. Why should this one 
>>>>> be different?
>>>>>
>>>>
>>>> Yes I understand this and 1 DT child node per LED out but...
>>>>
>>>> This device has a single register to control 3 LEDs brightness as a 
>>>> group and individual brightness
>>>> registers to control the LEDs independently to mix the LEDs to a 
>>>> specific color.
>>>>
>>>> There needs to be a way to control both so that developers can mix 
>>>> and adjust the individual RGB and
>>>> then control the brightness of the group during run time without 
>>>> touching the "mixing" value.
>>>>
>>>> I don't think a user needs nor would want to have 24 different LED 
>>>> nodes with 24 different brightness files.
>>>> Or with the LP5036 that would have 36 LED nodes.
>>>>
>>>> Table 1 in the data sheet shows how the outputs map to the control 
>>>> banks to the LED registers.
>>>
>>> Some time ago we had discussion with Vesa Jääskeläinen about possible
>>> approaches to RGB LEDs [0]. What seemed to be the most suitable
>>> variation of the discussed out-of-tree approach was the "color" property
>>> and array of color triplets defined in Device Tree per each color.
>>>
>>
>> Why does Device tree define the color?
>>
>> Rob indicated that Device tree is supposed to define the hardware.
>> This thread seems to be defining the operation.
> 
> Perceived colors produced by LEDs from different manufacturers may
> differ and this alone should be deemed a sufficient argument for having
> board specific color definitions.
> 
>> Shouldn't the color be done via user space and not dt?
> 
> I think that we should keep the userspace interface as simple
> as possible and backwards compatible with monochrome LEDs.
> 
> I also propose to avoid the introduction of a color sysfs
> property in favor of creating separate LED class devices
> for different "color ranges". The devices would drive the same
> LED but using different preset color levels.

On the other hand, scattering the control over the hardware
among multiple LED class devices would complicate extension
of pattern trigger with the support for RGB LEDs.

I looks like we will need the "color" sysfs file  anyway.

> We don't have to expose all device knobs to the userspace,
> but instead provide some predefined configurations. It would
> improve user experience by keeping LED class devices simple
> in use. It would be Device Tree designer's responsibility to
> provide color definitions that make sense for given RGB LED
> controller and RGB LED element configuration.
> 
> Registering color palette with devm_rgb_register() you proposed
> is also an option, but with one LED class device per color palette
> it would mean allowing for creation/destruction of LED class
> devices by any user having access to given LED's sysfs interface,
> which is really bad solution.

With the "color" sysfs file it will make more sense to allow for user
defined color palettes.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-21  7:32                 ` Jacek Anaszewski
@ 2018-12-21 13:05                   ` Dan Murphy
  2018-12-29 18:28                     ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2018-12-21 13:05 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 12/21/2018 01:32 AM, Jacek Anaszewski wrote:
> On 12/20/18 9:31 PM, Jacek Anaszewski wrote:
>> On 12/19/18 10:50 PM, Dan Murphy wrote:
>>> On 12/19/2018 03:36 PM, Jacek Anaszewski wrote:
>>>> Hi Dan and Pavel,
>>>>
>>>> On 12/19/18 9:41 PM, Dan Murphy wrote:
>>>>> Pavel
>>>>>
>>>>> On 12/19/2018 02:10 PM, Pavel Machek wrote:
>>>>>> On Wed 2018-12-19 13:41:18, Dan Murphy wrote:
>>>>>>> Pavel
>>>>>>>
>>>>>>> Thanks for the review.
>>>>>>>
>>>>>>> On 12/19/2018 01:34 PM, Pavel Machek wrote:
>>>>>>>> Hi!
>>>>>>>>
>>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
>>>>>>>>> +
>>>>>>>>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>>>>>>>>> +    &dev_attr_ctrl_bank_a_mix.attr,
>>>>>>>>> +    &dev_attr_ctrl_bank_b_mix.attr,
>>>>>>>>> +    &dev_attr_ctrl_bank_c_mix.attr,
>>>>>>>>> +    NULL
>>>>>>>>> +};
>>>>>>>>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
>>>>>>>>
>>>>>>>> ...
>>>>>>>>> +
>>>>>>>>> +static DEVICE_ATTR_WO(led1_mix);
>>>>>>>>> +static DEVICE_ATTR_WO(led2_mix);
>>>>>>>>> +static DEVICE_ATTR_WO(led3_mix);
>>>>>>>>> +
>>>>>>>>> +static struct attribute *lp5024_led_independent_attrs[] = {
>>>>>>>>> +    &dev_attr_led1_mix.attr,
>>>>>>>>> +    &dev_attr_led2_mix.attr,
>>>>>>>>> +    &dev_attr_led3_mix.attr,
>>>>>>>>> +    NULL
>>>>>>>>> +};
>>>>>>>>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
>>>>>>>>
>>>>>>>> Ok, so you are adding new sysfs files. Are they _really_ neccessary?
>>>>>>>> We'd like to have uniform interfaces for the leds.
>>>>>>>
>>>>>>> Yes I am adding these for this driver.
>>>>>>> They adjust the individual brightness of each LED connected (what the HW guys called mixing).
>>>>>>>
>>>>>>> The standard brightness sysfs adjusts all 3 LEDs simultaneously so that all 3 LEDs brightness are
>>>>>>> uniform.
>>>>>>
>>>>>> 1 LED, 1 brightness file... that's what we do. Why should this one be different?
>>>>>>
>>>>>
>>>>> Yes I understand this and 1 DT child node per LED out but...
>>>>>
>>>>> This device has a single register to control 3 LEDs brightness as a group and individual brightness
>>>>> registers to control the LEDs independently to mix the LEDs to a specific color.
>>>>>
>>>>> There needs to be a way to control both so that developers can mix and adjust the individual RGB and
>>>>> then control the brightness of the group during run time without touching the "mixing" value.
>>>>>
>>>>> I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
>>>>> Or with the LP5036 that would have 36 LED nodes.
>>>>>
>>>>> Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.
>>>>
>>>> Some time ago we had discussion with Vesa Jääskeläinen about possible
>>>> approaches to RGB LEDs [0]. What seemed to be the most suitable
>>>> variation of the discussed out-of-tree approach was the "color" property
>>>> and array of color triplets defined in Device Tree per each color.
>>>>
>>>
>>> Why does Device tree define the color?
>>>
>>> Rob indicated that Device tree is supposed to define the hardware.
>>> This thread seems to be defining the operation.
>>
>> Perceived colors produced by LEDs from different manufacturers may
>> differ and this alone should be deemed a sufficient argument for having
>> board specific color definitions.
>>
>>> Shouldn't the color be done via user space and not dt?
>>
>> I think that we should keep the userspace interface as simple
>> as possible and backwards compatible with monochrome LEDs.
>>
>> I also propose to avoid the introduction of a color sysfs
>> property in favor of creating separate LED class devices
>> for different "color ranges". The devices would drive the same
>> LED but using different preset color levels.
> 
> On the other hand, scattering the control over the hardware
> among multiple LED class devices would complicate extension
> of pattern trigger with the support for RGB LEDs.
> 
> I looks like we will need the "color" sysfs file  anyway.
> 
>> We don't have to expose all device knobs to the userspace,
>> but instead provide some predefined configurations. It would
>> improve user experience by keeping LED class devices simple
>> in use. It would be Device Tree designer's responsibility to
>> provide color definitions that make sense for given RGB LED
>> controller and RGB LED element configuration.
>>
>> Registering color palette with devm_rgb_register() you proposed
>> is also an option, but with one LED class device per color palette
>> it would mean allowing for creation/destruction of LED class
>> devices by any user having access to given LED's sysfs interface,
>> which is really bad solution.
> 
> With the "color" sysfs file it will make more sense to allow for user
> defined color palettes.
> 

I think defining these values in the device tree or acpi severely limits the devices
capabilities.  Especially in development phases.  If the knobs were exposed then the user space
can create new experiences.  The color definition should be an absolute color defined in the dt and
either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
of the user experience and the dt/acpi needs to set the capabilities.

I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.

Maybe the framework could take these groups and combine/group them into a single node with the groups colors.

Dan
-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2018-12-19 16:26 ` [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver Dan Murphy
@ 2018-12-28 23:53   ` Rob Herring
  2018-12-31 18:54     ` Dan Murphy
  2019-01-08 20:33   ` Jacek Anaszewski
  1 sibling, 1 reply; 106+ messages in thread
From: Rob Herring @ 2018-12-28 23:53 UTC (permalink / raw)
  To: Dan Murphy; +Cc: jacek.anaszewski, pavel, devicetree, linux-kernel, linux-leds

On Wed, Dec 19, 2018 at 10:26:25AM -0600, Dan Murphy wrote:
> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
> or as part of a control bank group.  These devices have the ability
> to adjust the mixing control for the RGB LEDs to obtain different colors
> independent of the overall brightness of the LED grouping.
> 
> Datasheet:
> http://www.ti.com/lit/ds/symlink/lp5024.pdf
> 
> Signed-off-by: Dan Murphy <dmurphy@ti.com>
> ---
>  .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>  1 file changed, 63 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
> 
> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
> new file mode 100644
> index 000000000000..9567aa6f7813
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
> @@ -0,0 +1,63 @@
> +* Texas Instruments - LP5024/18 RGB LED driver
> +
> +The LM3692x is an ultra-compact, highly efficient,
> +white-LED driver designed for LCD display backlighting.

Leftover copy-n-paste?

> +
> +The main difference between the LP5024 and L5018 is the number of
> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
> +LP5018 supports eighteen strings.
> +
> +Required properties:
> +	- compatible:
> +		"ti,lp5018"
> +		"ti,lp5024"
> +	- reg :  I2C slave address
> +	- #address-cells : 1
> +	- #size-cells : 0
> +
> +Optional properties:
> +	- enable-gpios : gpio pin to enable/disable the device.
> +	- vled-supply : LED supply
> +
> +Required child properties:
> +	- reg : Is the child node iteration.
> +	- led-sources : LP5024 - 0 - 7
> +			LP5018 - 0 - 5
> +			Declares the LED string or strings that the child node
> +			will control.  If ti,control-bank is set then this
> +			property will contain multiple LED IDs.
> +
> +Optional child properties:
> +	- label : see Documentation/devicetree/bindings/leds/common.txt
> +	- linux,default-trigger :
> +	   see Documentation/devicetree/bindings/leds/common.txt
> +	- ti,control-bank : Indicates that the LED strings declared in the
> +			    led-sources property are grouped within a control
> +			    bank for brightness and mixing control.
> +
> +Example:
> +
> +led-controller@28 {
> +	compatible = "ti,lp5024";
> +	reg = <0x28>;
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
> +	vled-supply = <&vbatt>;
> +
> +	led@0 {
> +		reg = <0>;
> +		led-sources = <1>;
> +	};
> +
> +	led@1 {
> +		reg = <1>;
> +		led-sources = <0 6>;
> +		ti,control-bank;
> +	};
> +
> +}
> +
> +For more product information please see the link below:
> +http://www.ti.com/lit/ds/symlink/lp5024.pdf
> -- 
> 2.20.0.rc2.7.g965798d1f2
> 

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-21 13:05                   ` Dan Murphy
@ 2018-12-29 18:28                     ` Jacek Anaszewski
  2018-12-29 19:07                       ` Pavel Machek
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2018-12-29 18:28 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek; +Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 12/21/18 2:05 PM, Dan Murphy wrote:
> On 12/21/2018 01:32 AM, Jacek Anaszewski wrote:
>> On 12/20/18 9:31 PM, Jacek Anaszewski wrote:
>>> On 12/19/18 10:50 PM, Dan Murphy wrote:
>>>> On 12/19/2018 03:36 PM, Jacek Anaszewski wrote:
>>>>> Hi Dan and Pavel,
>>>>>
>>>>> On 12/19/18 9:41 PM, Dan Murphy wrote:
>>>>>> Pavel
>>>>>>
>>>>>> On 12/19/2018 02:10 PM, Pavel Machek wrote:
>>>>>>> On Wed 2018-12-19 13:41:18, Dan Murphy wrote:
>>>>>>>> Pavel
>>>>>>>>
>>>>>>>> Thanks for the review.
>>>>>>>>
>>>>>>>> On 12/19/2018 01:34 PM, Pavel Machek wrote:
>>>>>>>>> Hi!
>>>>>>>>>
>>>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>>>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>>>>>>>>>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
>>>>>>>>>> +
>>>>>>>>>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>>>>>>>>>> +    &dev_attr_ctrl_bank_a_mix.attr,
>>>>>>>>>> +    &dev_attr_ctrl_bank_b_mix.attr,
>>>>>>>>>> +    &dev_attr_ctrl_bank_c_mix.attr,
>>>>>>>>>> +    NULL
>>>>>>>>>> +};
>>>>>>>>>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
>>>>>>>>>
>>>>>>>>> ...
>>>>>>>>>> +
>>>>>>>>>> +static DEVICE_ATTR_WO(led1_mix);
>>>>>>>>>> +static DEVICE_ATTR_WO(led2_mix);
>>>>>>>>>> +static DEVICE_ATTR_WO(led3_mix);
>>>>>>>>>> +
>>>>>>>>>> +static struct attribute *lp5024_led_independent_attrs[] = {
>>>>>>>>>> +    &dev_attr_led1_mix.attr,
>>>>>>>>>> +    &dev_attr_led2_mix.attr,
>>>>>>>>>> +    &dev_attr_led3_mix.attr,
>>>>>>>>>> +    NULL
>>>>>>>>>> +};
>>>>>>>>>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
>>>>>>>>>
>>>>>>>>> Ok, so you are adding new sysfs files. Are they _really_ neccessary?
>>>>>>>>> We'd like to have uniform interfaces for the leds.
>>>>>>>>
>>>>>>>> Yes I am adding these for this driver.
>>>>>>>> They adjust the individual brightness of each LED connected (what the HW guys called mixing).
>>>>>>>>
>>>>>>>> The standard brightness sysfs adjusts all 3 LEDs simultaneously so that all 3 LEDs brightness are
>>>>>>>> uniform.
>>>>>>>
>>>>>>> 1 LED, 1 brightness file... that's what we do. Why should this one be different?
>>>>>>>
>>>>>>
>>>>>> Yes I understand this and 1 DT child node per LED out but...
>>>>>>
>>>>>> This device has a single register to control 3 LEDs brightness as a group and individual brightness
>>>>>> registers to control the LEDs independently to mix the LEDs to a specific color.
>>>>>>
>>>>>> There needs to be a way to control both so that developers can mix and adjust the individual RGB and
>>>>>> then control the brightness of the group during run time without touching the "mixing" value.
>>>>>>
>>>>>> I don't think a user needs nor would want to have 24 different LED nodes with 24 different brightness files.
>>>>>> Or with the LP5036 that would have 36 LED nodes.
>>>>>>
>>>>>> Table 1 in the data sheet shows how the outputs map to the control banks to the LED registers.
>>>>>
>>>>> Some time ago we had discussion with Vesa Jääskeläinen about possible
>>>>> approaches to RGB LEDs [0]. What seemed to be the most suitable
>>>>> variation of the discussed out-of-tree approach was the "color" property
>>>>> and array of color triplets defined in Device Tree per each color.
>>>>>
>>>>
>>>> Why does Device tree define the color?
>>>>
>>>> Rob indicated that Device tree is supposed to define the hardware.
>>>> This thread seems to be defining the operation.
>>>
>>> Perceived colors produced by LEDs from different manufacturers may
>>> differ and this alone should be deemed a sufficient argument for having
>>> board specific color definitions.
>>>
>>>> Shouldn't the color be done via user space and not dt?
>>>
>>> I think that we should keep the userspace interface as simple
>>> as possible and backwards compatible with monochrome LEDs.
>>>
>>> I also propose to avoid the introduction of a color sysfs
>>> property in favor of creating separate LED class devices
>>> for different "color ranges". The devices would drive the same
>>> LED but using different preset color levels.
>>
>> On the other hand, scattering the control over the hardware
>> among multiple LED class devices would complicate extension
>> of pattern trigger with the support for RGB LEDs.
>>
>> I looks like we will need the "color" sysfs file  anyway.
>>
>>> We don't have to expose all device knobs to the userspace,
>>> but instead provide some predefined configurations. It would
>>> improve user experience by keeping LED class devices simple
>>> in use. It would be Device Tree designer's responsibility to
>>> provide color definitions that make sense for given RGB LED
>>> controller and RGB LED element configuration.
>>>
>>> Registering color palette with devm_rgb_register() you proposed
>>> is also an option, but with one LED class device per color palette
>>> it would mean allowing for creation/destruction of LED class
>>> devices by any user having access to given LED's sysfs interface,
>>> which is really bad solution.
>>
>> With the "color" sysfs file it will make more sense to allow for user
>> defined color palettes.
>>
> 
> I think defining these values in the device tree or acpi severely limits the devices
> capabilities.  Especially in development phases.  If the knobs were exposed then the user space
> can create new experiences.  The color definition should be an absolute color defined in the dt and
> either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
> of the user experience and the dt/acpi needs to set the capabilities.
> 
> I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
> 
> Maybe the framework could take these groups and combine/group them into a single node with the groups colors.

There is still HSV approach [0] in store. One problem with proposed
implementation is fixed algorithm of RGB <-> HSV color space conversion.
Maybe allowing for some board specific adjustments in DT would add
more flexibility.

[0] https://lkml.org/lkml/2017/8/31/255

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-29 18:28                     ` Jacek Anaszewski
@ 2018-12-29 19:07                       ` Pavel Machek
  2018-12-30 17:09                         ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2018-12-29 19:07 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

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

Hi!

> >>With the "color" sysfs file it will make more sense to allow for user
> >>defined color palettes.
> >>
> >
> >I think defining these values in the device tree or acpi severely limits the devices
> >capabilities.  Especially in development phases.  If the knobs were exposed then the user space
> >can create new experiences.  The color definition should be an absolute color defined in the dt and
> >either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
> >of the user experience and the dt/acpi needs to set the capabilities.
> >
> >I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
> >
> >Maybe the framework could take these groups and combine/group them into a single node with the groups colors.
> 
> There is still HSV approach [0] in store. One problem with proposed
> implementation is fixed algorithm of RGB <-> HSV color space conversion.
> Maybe allowing for some board specific adjustments in DT would add
> more flexibility.
> 
> [0] https://lkml.org/lkml/2017/8/31/255

Yes we could do HSV. Problem is that that we do not really have RGB
available. We do have integers for red, green and blue, but they do
not correspond to RGB colorspace.

Anyway, this should not be driver specific; all drivers should use one
interface.

Best regards,
									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-29 19:07                       ` Pavel Machek
@ 2018-12-30 17:09                         ` Jacek Anaszewski
  2018-12-30 17:35                           ` Pavel Machek
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2018-12-30 17:09 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

On 12/29/18 8:07 PM, Pavel Machek wrote:
> Hi!
> 
>>>> With the "color" sysfs file it will make more sense to allow for user
>>>> defined color palettes.
>>>>
>>>
>>> I think defining these values in the device tree or acpi severely limits the devices
>>> capabilities.  Especially in development phases.  If the knobs were exposed then the user space
>>> can create new experiences.  The color definition should be an absolute color defined in the dt and
>>> either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
>>> of the user experience and the dt/acpi needs to set the capabilities.
>>>
>>> I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
>>>
>>> Maybe the framework could take these groups and combine/group them into a single node with the groups colors.
>>
>> There is still HSV approach [0] in store. One problem with proposed
>> implementation is fixed algorithm of RGB <-> HSV color space conversion.
>> Maybe allowing for some board specific adjustments in DT would add
>> more flexibility.
>>
>> [0] https://lkml.org/lkml/2017/8/31/255
> 
> Yes we could do HSV. Problem is that that we do not really have RGB
> available. We do have integers for red, green and blue, but they do
> not correspond to RGB colorspace.

OK, so conversion from HSV to RGB would only increase the aberration.
So, let's stick to RGB - we've got to have some stable ground and this
is something that the hardware at least pretends to be compliant with.

Our problem is how to set the color atomically. With HSV approach we
were to obviate the problem by mapping brightness file to the "V"
component of that color space, and write all H,S and V values to the
hardware only on write to brightness file.

We could apply similar approach in case of RGB LED class device.
We would have four files instead of a single brightness file:
red, green, blue and main_color. First three would accept values
within 0-255 range, and main_color would accept one of
"red", "green" or "blue". LED RGB class driver would write all
color components to the hardware only on write to the file corresponding
to the main_color. Also LED Trigger core would be taught to map
brightness value to the main_color for RGB LEDs.

Of course a new internal kernel API for setting color would
have to be provided for use by dedicated RGB triggers.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-30 17:09                         ` Jacek Anaszewski
@ 2018-12-30 17:35                           ` Pavel Machek
  2018-12-31 15:43                             ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2018-12-30 17:35 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

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

On Sun 2018-12-30 18:09:35, Jacek Anaszewski wrote:
> On 12/29/18 8:07 PM, Pavel Machek wrote:
> >Hi!
> >
> >>>>With the "color" sysfs file it will make more sense to allow for user
> >>>>defined color palettes.
> >>>>
> >>>
> >>>I think defining these values in the device tree or acpi severely limits the devices
> >>>capabilities.  Especially in development phases.  If the knobs were exposed then the user space
> >>>can create new experiences.  The color definition should be an absolute color defined in the dt and
> >>>either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
> >>>of the user experience and the dt/acpi needs to set the capabilities.
> >>>
> >>>I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
> >>>
> >>>Maybe the framework could take these groups and combine/group them into a single node with the groups colors.
> >>
> >>There is still HSV approach [0] in store. One problem with proposed
> >>implementation is fixed algorithm of RGB <-> HSV color space conversion.
> >>Maybe allowing for some board specific adjustments in DT would add
> >>more flexibility.
> >>
> >>[0] https://lkml.org/lkml/2017/8/31/255
> >
> >Yes we could do HSV. Problem is that that we do not really have RGB
> >available. We do have integers for red, green and blue, but they do
> >not correspond to RGB colorspace.
> 
> OK, so conversion from HSV to RGB would only increase the aberration.
> So, let's stick to RGB - we've got to have some stable ground and this
> is something that the hardware at least pretends to be compliant
>with.

I'm not saying that we should stick to RGB. I'm just saying that
problem is complex.

And no, hardware does not even pretend to be compliant with RGB color
model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
particular, in RGB there is non-linear brightness curve.

> Our problem is how to set the color atomically. With HSV approach we
> were to obviate the problem by mapping brightness file to the "V"
> component of that color space, and write all H,S and V values to the
> hardware only on write to brightness file.

I'm not sure how realistic the "atomic color" problem is. Computers
are way faster than human vision.

I believe problem to start with is the "white" problem. Setting
R=G=B=255 will _not_ result in anything close to white light on
hardware I have.

Anyway,

									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-30 17:35                           ` Pavel Machek
@ 2018-12-31 15:43                             ` Jacek Anaszewski
  2018-12-31 15:47                               ` Jacek Anaszewski
  2018-12-31 16:28                               ` Pavel Machek
  0 siblings, 2 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2018-12-31 15:43 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

On 12/30/18 6:35 PM, Pavel Machek wrote:
> On Sun 2018-12-30 18:09:35, Jacek Anaszewski wrote:
>> On 12/29/18 8:07 PM, Pavel Machek wrote:
>>> Hi!
>>>
>>>>>> With the "color" sysfs file it will make more sense to allow for user
>>>>>> defined color palettes.
>>>>>>
>>>>>
>>>>> I think defining these values in the device tree or acpi severely limits the devices
>>>>> capabilities.  Especially in development phases.  If the knobs were exposed then the user space
>>>>> can create new experiences.  The color definition should be an absolute color defined in the dt and
>>>>> either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
>>>>> of the user experience and the dt/acpi needs to set the capabilities.
>>>>>
>>>>> I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
>>>>>
>>>>> Maybe the framework could take these groups and combine/group them into a single node with the groups colors.
>>>>
>>>> There is still HSV approach [0] in store. One problem with proposed
>>>> implementation is fixed algorithm of RGB <-> HSV color space conversion.
>>>> Maybe allowing for some board specific adjustments in DT would add
>>>> more flexibility.
>>>>
>>>> [0] https://lkml.org/lkml/2017/8/31/255
>>>
>>> Yes we could do HSV. Problem is that that we do not really have RGB
>>> available. We do have integers for red, green and blue, but they do
>>> not correspond to RGB colorspace.
>>
>> OK, so conversion from HSV to RGB would only increase the aberration.
>> So, let's stick to RGB - we've got to have some stable ground and this
>> is something that the hardware at least pretends to be compliant
>> with.
> 
> I'm not saying that we should stick to RGB. I'm just saying that
> problem is complex.
> 
> And no, hardware does not even pretend to be compliant with RGB color
> model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
> particular, in RGB there is non-linear brightness curve.

Quotation from the wiki page you referred to:

"RGB is a device-dependent color model: different devices detect or
reproduce a given RGB value differently, since the color elements (such
as phosphors or dyes) and their response to the individual R, G, and B
levels vary from manufacturer to manufacturer, or even in the same
device over time. Thus an RGB value does not define the same color
across devices without some kind of color management"

This claim alone leaves much room for the manufacturers to pretend that
their devices are compliant with RGB model.

And the documentation of the hardware the discussed driver is for
also refers to RGB model in many places - e.g. see Table 1, page 15
in the document [0], where mapping of output triplets to an RGB module
is shown.

One thing that I missed is that the discussed hardware provides
LEDn_BRIGHTNESS registers for each RGB LED module, that can be
configured to set color intensity in linear or logarithmic fashion.

Actually this stands in contradiction with RGB model, since
change of "color intensity" means change of all RGB components.

We could use brightness file as for monochrome LEDs for that,
but we'd need to come up with consistent interface semantics
for all devices, also those which don't have corresponding
functionality. Probably this is the place where we could apply
some RGB<->HSV conversion, as color intensity feels something
more of HSV's saturation and value.

It would be good to hear from Dan how that looks in reality
in case of lp5024 device.

>> Our problem is how to set the color atomically. With HSV approach we
>> were to obviate the problem by mapping brightness file to the "V"
>> component of that color space, and write all H,S and V values to the
>> hardware only on write to brightness file.
> 
> I'm not sure how realistic the "atomic color" problem is. Computers
> are way faster than human vision.

With LEDn_BRIGHTNESS registers of lp5024 it seems that we need the
ability for grouping LEDs in triplets and be able to set their intensity
with a single write operation.

> I believe problem to start with is the "white" problem. Setting
> R=G=B=255 will _not_ result in anything close to white light on
> hardware I have.

RGBW LED controllers solve this problem. For the devices without
white/amber we cannot do more than the hardware allows for.

[0] http://www.ti.com/lit/ds/symlink/lp5024.pdf

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-31 15:43                             ` Jacek Anaszewski
@ 2018-12-31 15:47                               ` Jacek Anaszewski
  2018-12-31 19:15                                 ` Dan Murphy
  2018-12-31 16:28                               ` Pavel Machek
  1 sibling, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2018-12-31 15:47 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

On 12/31/18 4:43 PM, Jacek Anaszewski wrote:
> On 12/30/18 6:35 PM, Pavel Machek wrote:
>> On Sun 2018-12-30 18:09:35, Jacek Anaszewski wrote:
>>> On 12/29/18 8:07 PM, Pavel Machek wrote:
>>>> Hi!
>>>>
>>>>>>> With the "color" sysfs file it will make more sense to allow for 
>>>>>>> user
>>>>>>> defined color palettes.
>>>>>>>
>>>>>>
>>>>>> I think defining these values in the device tree or acpi severely 
>>>>>> limits the devices
>>>>>> capabilities.  Especially in development phases.  If the knobs 
>>>>>> were exposed then the user space
>>>>>> can create new experiences.  The color definition should be an 
>>>>>> absolute color defined in the dt and
>>>>>> either the framework or user space needs to mix these 
>>>>>> appropriately.  IMO user space should set the policy
>>>>>> of the user experience and the dt/acpi needs to set the capabilities.
>>>>>>
>>>>>> I do like Pavels idea on defining the more standard binding 
>>>>>> pattern to "group" leds into a single group.
>>>>>>
>>>>>> Maybe the framework could take these groups and combine/group them 
>>>>>> into a single node with the groups colors.
>>>>>
>>>>> There is still HSV approach [0] in store. One problem with proposed
>>>>> implementation is fixed algorithm of RGB <-> HSV color space 
>>>>> conversion.
>>>>> Maybe allowing for some board specific adjustments in DT would add
>>>>> more flexibility.
>>>>>
>>>>> [0] https://lkml.org/lkml/2017/8/31/255
>>>>
>>>> Yes we could do HSV. Problem is that that we do not really have RGB
>>>> available. We do have integers for red, green and blue, but they do
>>>> not correspond to RGB colorspace.
>>>
>>> OK, so conversion from HSV to RGB would only increase the aberration.
>>> So, let's stick to RGB - we've got to have some stable ground and this
>>> is something that the hardware at least pretends to be compliant
>>> with.
>>
>> I'm not saying that we should stick to RGB. I'm just saying that
>> problem is complex.
>>
>> And no, hardware does not even pretend to be compliant with RGB color
>> model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
>> particular, in RGB there is non-linear brightness curve.
> 
> Quotation from the wiki page you referred to:
> 
> "RGB is a device-dependent color model: different devices detect or
> reproduce a given RGB value differently, since the color elements (such
> as phosphors or dyes) and their response to the individual R, G, and B
> levels vary from manufacturer to manufacturer, or even in the same
> device over time. Thus an RGB value does not define the same color
> across devices without some kind of color management"
> 
> This claim alone leaves much room for the manufacturers to pretend that
> their devices are compliant with RGB model.
> 
> And the documentation of the hardware the discussed driver is for
> also refers to RGB model in many places - e.g. see Table 1, page 15
> in the document [0], where mapping of output triplets to an RGB module
> is shown.
> 
> One thing that I missed is that the discussed hardware provides
> LEDn_BRIGHTNESS registers for each RGB LED module, that can be
> configured to set color intensity in linear or logarithmic fashion.
> 
> Actually this stands in contradiction with RGB model, since
> change of "color intensity" means change of all RGB components.
> 
> We could use brightness file as for monochrome LEDs for that,

Here I mean brightness file in addition to the previously proposed
red, green and blue files.

> but we'd need to come up with consistent interface semantics
> for all devices, also those which don't have corresponding
> functionality. Probably this is the place where we could apply
> some RGB<->HSV conversion, as color intensity feels something
> more of HSV's saturation and value.
> 
> It would be good to hear from Dan how that looks in reality
> in case of lp5024 device.
> 
>>> Our problem is how to set the color atomically. With HSV approach we
>>> were to obviate the problem by mapping brightness file to the "V"
>>> component of that color space, and write all H,S and V values to the
>>> hardware only on write to brightness file.
>>
>> I'm not sure how realistic the "atomic color" problem is. Computers
>> are way faster than human vision.
> 
> With LEDn_BRIGHTNESS registers of lp5024 it seems that we need the
> ability for grouping LEDs in triplets and be able to set their intensity
> with a single write operation.
> 
>> I believe problem to start with is the "white" problem. Setting
>> R=G=B=255 will _not_ result in anything close to white light on
>> hardware I have.
> 
> RGBW LED controllers solve this problem. For the devices without
> white/amber we cannot do more than the hardware allows for.
> 
> [0] http://www.ti.com/lit/ds/symlink/lp5024.pdf
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-31 15:43                             ` Jacek Anaszewski
  2018-12-31 15:47                               ` Jacek Anaszewski
@ 2018-12-31 16:28                               ` Pavel Machek
  2019-01-01 14:26                                 ` Jacek Anaszewski
  1 sibling, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2018-12-31 16:28 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

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

Hi!

> >>>>There is still HSV approach [0] in store. One problem with proposed
> >>>>implementation is fixed algorithm of RGB <-> HSV color space conversion.
> >>>>Maybe allowing for some board specific adjustments in DT would add
> >>>>more flexibility.
> >>>>
> >>>>[0] https://lkml.org/lkml/2017/8/31/255
> >>>
> >>>Yes we could do HSV. Problem is that that we do not really have RGB
> >>>available. We do have integers for red, green and blue, but they do
> >>>not correspond to RGB colorspace.
> >>
> >>OK, so conversion from HSV to RGB would only increase the aberration.
> >>So, let's stick to RGB - we've got to have some stable ground and this
> >>is something that the hardware at least pretends to be compliant
> >>with.
> >
> >I'm not saying that we should stick to RGB. I'm just saying that
> >problem is complex.
> >
> >And no, hardware does not even pretend to be compliant with RGB color
> >model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
> >particular, in RGB there is non-linear brightness curve.
> 
> Quotation from the wiki page you referred to:
> 
> "RGB is a device-dependent color model: different devices detect or
> reproduce a given RGB value differently, since the color elements (such
> as phosphors or dyes) and their response to the individual R, G, and B
> levels vary from manufacturer to manufacturer, or even in the same
> device over time. Thus an RGB value does not define the same color
> across devices without some kind of color management"
> 
> This claim alone leaves much room for the manufacturers to pretend that
> their devices are compliant with RGB model.

Much room, but everyone agrees that R=G=B=255 should be some kind of
white, and what other colors "approximately" mean. 

I have two monitors, and no, colors don't match.

Do you have access to RGB led? Try to compare two monitors, and then
RGB led with monitor. RGB led will be _way_ off.

This chart makes sense:

https://www.rapidtables.com/web/color/RGB_Color.html

Try it on your LED device...

> >I believe problem to start with is the "white" problem. Setting
> >R=G=B=255 will _not_ result in anything close to white light on
> >hardware I have.
> 
> RGBW LED controllers solve this problem. For the devices without
> white/amber we cannot do more than the hardware allows for.

But the hardware can do some kind of white. It is just that R=G=B=255
will result in green-ish-blue and something like R=255, G=50, B=10 is
neccessary to get approximation of white.

IMO good start would be to specify what kind of intensities are
neccessary to approximate white. And then try converting from RGB to
led intensities, and see if it somehow works.
									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] 106+ messages in thread

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2018-12-28 23:53   ` Rob Herring
@ 2018-12-31 18:54     ` Dan Murphy
  0 siblings, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2018-12-31 18:54 UTC (permalink / raw)
  To: Rob Herring; +Cc: jacek.anaszewski, pavel, devicetree, linux-kernel, linux-leds

Rob

On 12/28/18 5:53 PM, Rob Herring wrote:
> On Wed, Dec 19, 2018 at 10:26:25AM -0600, Dan Murphy wrote:
>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>> or as part of a control bank group.  These devices have the ability
>> to adjust the mixing control for the RGB LEDs to obtain different colors
>> independent of the overall brightness of the LED grouping.
>>
>> Datasheet:
>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>
>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>> ---
>>  .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>  1 file changed, 63 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>
>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>> new file mode 100644
>> index 000000000000..9567aa6f7813
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>> @@ -0,0 +1,63 @@
>> +* Texas Instruments - LP5024/18 RGB LED driver
>> +
>> +The LM3692x is an ultra-compact, highly efficient,
>> +white-LED driver designed for LCD display backlighting.
> 
> Leftover copy-n-paste?
> 

ACK
I have this updated for v2.

>> +
>> +The main difference between the LP5024 and L5018 is the number of
>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>> +LP5018 supports eighteen strings.
>> +
>> +Required properties:
>> +	- compatible:
>> +		"ti,lp5018"
>> +		"ti,lp5024"
>> +	- reg :  I2C slave address
>> +	- #address-cells : 1
>> +	- #size-cells : 0
>> +
>> +Optional properties:
>> +	- enable-gpios : gpio pin to enable/disable the device.
>> +	- vled-supply : LED supply
>> +
>> +Required child properties:
>> +	- reg : Is the child node iteration.
>> +	- led-sources : LP5024 - 0 - 7
>> +			LP5018 - 0 - 5
>> +			Declares the LED string or strings that the child node
>> +			will control.  If ti,control-bank is set then this
>> +			property will contain multiple LED IDs.
>> +
>> +Optional child properties:
>> +	- label : see Documentation/devicetree/bindings/leds/common.txt
>> +	- linux,default-trigger :
>> +	   see Documentation/devicetree/bindings/leds/common.txt
>> +	- ti,control-bank : Indicates that the LED strings declared in the
>> +			    led-sources property are grouped within a control
>> +			    bank for brightness and mixing control.
>> +
>> +Example:
>> +
>> +led-controller@28 {
>> +	compatible = "ti,lp5024";
>> +	reg = <0x28>;
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
>> +
>> +	enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>> +	vled-supply = <&vbatt>;
>> +
>> +	led@0 {
>> +		reg = <0>;
>> +		led-sources = <1>;
>> +	};
>> +
>> +	led@1 {
>> +		reg = <1>;
>> +		led-sources = <0 6>;
>> +		ti,control-bank;
>> +	};
>> +
>> +}
>> +
>> +For more product information please see the link below:
>> +http://www.ti.com/lit/ds/symlink/lp5024.pdf
>> -- 
>> 2.20.0.rc2.7.g965798d1f2
>>


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-31 15:47                               ` Jacek Anaszewski
@ 2018-12-31 19:15                                 ` Dan Murphy
  2019-01-01 14:42                                   ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2018-12-31 19:15 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 12/31/18 9:47 AM, Jacek Anaszewski wrote:
> On 12/31/18 4:43 PM, Jacek Anaszewski wrote:
>> On 12/30/18 6:35 PM, Pavel Machek wrote:
>>> On Sun 2018-12-30 18:09:35, Jacek Anaszewski wrote:
>>>> On 12/29/18 8:07 PM, Pavel Machek wrote:
>>>>> Hi!
>>>>>
>>>>>>>> With the "color" sysfs file it will make more sense to allow for user
>>>>>>>> defined color palettes.
>>>>>>>>
>>>>>>>
>>>>>>> I think defining these values in the device tree or acpi severely limits the devices
>>>>>>> capabilities.  Especially in development phases.  If the knobs were exposed then the user space
>>>>>>> can create new experiences.  The color definition should be an absolute color defined in the dt and
>>>>>>> either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
>>>>>>> of the user experience and the dt/acpi needs to set the capabilities.
>>>>>>>
>>>>>>> I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
>>>>>>>
>>>>>>> Maybe the framework could take these groups and combine/group them into a single node with the groups colors.
>>>>>>
>>>>>> There is still HSV approach [0] in store. One problem with proposed
>>>>>> implementation is fixed algorithm of RGB <-> HSV color space conversion.
>>>>>> Maybe allowing for some board specific adjustments in DT would add
>>>>>> more flexibility.
>>>>>>
>>>>>> [0] https://lkml.org/lkml/2017/8/31/255
>>>>>
>>>>> Yes we could do HSV. Problem is that that we do not really have RGB
>>>>> available. We do have integers for red, green and blue, but they do
>>>>> not correspond to RGB colorspace.
>>>>
>>>> OK, so conversion from HSV to RGB would only increase the aberration.
>>>> So, let's stick to RGB - we've got to have some stable ground and this
>>>> is something that the hardware at least pretends to be compliant
>>>> with.
>>>
>>> I'm not saying that we should stick to RGB. I'm just saying that
>>> problem is complex.
>>>
>>> And no, hardware does not even pretend to be compliant with RGB color
>>> model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
>>> particular, in RGB there is non-linear brightness curve.
>>
>> Quotation from the wiki page you referred to:
>>
>> "RGB is a device-dependent color model: different devices detect or
>> reproduce a given RGB value differently, since the color elements (such
>> as phosphors or dyes) and their response to the individual R, G, and B
>> levels vary from manufacturer to manufacturer, or even in the same
>> device over time. Thus an RGB value does not define the same color
>> across devices without some kind of color management"
>>
>> This claim alone leaves much room for the manufacturers to pretend that
>> their devices are compliant with RGB model.
>>
>> And the documentation of the hardware the discussed driver is for
>> also refers to RGB model in many places - e.g. see Table 1, page 15
>> in the document [0], where mapping of output triplets to an RGB module
>> is shown.
>>
>> One thing that I missed is that the discussed hardware provides
>> LEDn_BRIGHTNESS registers for each RGB LED module, that can be
>> configured to set color intensity in linear or logarithmic fashion.
>>
>> Actually this stands in contradiction with RGB model, since
>> change of "color intensity" means change of all RGB components.
>>
>> We could use brightness file as for monochrome LEDs for that,
> 
> Here I mean brightness file in addition to the previously proposed
> red, green and blue files.
> 
>> but we'd need to come up with consistent interface semantics
>> for all devices, also those which don't have corresponding
>> functionality. Probably this is the place where we could apply
>> some RGB<->HSV conversion, as color intensity feels something
>> more of HSV's saturation and value.
>>
>> It would be good to hear from Dan how that looks in reality
>> in case of lp5024 device.

Sorry for the non-response I have had a passing in my family and have not been at my
computer for some time.

I am not seeing how HSV will fit into this device.  Not sure what the V is in HSV.
I am still not a fan of defining colors in the kernel.  I think the user space needs to do this based
on information it is given.  When I look at Android the user space sets all the policies of the hardware
the kernel just provides the vehicle to hardware.  I think defining any set colors in the kernel for devices
that have a full color spectrum palette is very restricting.  The kernel should indicate the absolute colors
available and not the colors that are allowed.  So in this case we indicate that a Red, green and blue LED are
available or that the palette is variable.  Or in the case of a white LED driver we just say white.

In the case of this device there are RGB outputs that are grouped in clusters and controlled by the LEDn_BRIGHTNESS
register.  This is what the brightness file is mapped to.  Within that cluster the individual intensity of the RGB can 
be modified via the OUTn_color register.  Not knowing what color LED is on what output means the sysfs node has to be left generic.

So as Pavel pointed out white would need to be achieved through the RGB individual LEDs being set to certain values and
the difuser disfusing the light to achieve the color.  This was done on the original DROID device with a RGB and we
were able to get a "white" color but had to set the RGB LEDs to different values.  For this device, once the color is
achieved there may be no reason to adjust the color so adjusting the overall brightness of the LEDs without adjusting the
individual color can be done with a single write and look seamless to the user.
Or other colors can be tuned by setting the unneeded colors in the OUTn_color to 0.

These RGB LED clusters can also be grouped into LED banks as well so that all LEDs of the same color within the group will have 
the same color gradient and brightness.  This is achieved with the BANK_X_COLOR and BRIGHTNESS registers.

Again I am not sure how the HSV would work for this device since there is no reason to create a node for each LED output.
As the overall brightness of the cluster or bank is controlled by a single brightness file.

Dan

>>
>>>> Our problem is how to set the color atomically. With HSV approach we
>>>> were to obviate the problem by mapping brightness file to the "V"
>>>> component of that color space, and write all H,S and V values to the
>>>> hardware only on write to brightness file.
>>>
>>> I'm not sure how realistic the "atomic color" problem is. Computers
>>> are way faster than human vision.
>>
>> With LEDn_BRIGHTNESS registers of lp5024 it seems that we need the
>> ability for grouping LEDs in triplets and be able to set their intensity
>> with a single write operation.
>>
>>> I believe problem to start with is the "white" problem. Setting
>>> R=G=B=255 will _not_ result in anything close to white light on
>>> hardware I have.
>>
>> RGBW LED controllers solve this problem. For the devices without
>> white/amber we cannot do more than the hardware allows for.
>>
>> [0] http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-20 12:40               ` Vesa Jääskeläinen
  2018-12-20 13:56                 ` Dan Murphy
@ 2019-01-01 13:45                 ` Vesa Jääskeläinen
  2019-01-03 22:05                   ` Jacek Anaszewski
  1 sibling, 1 reply; 106+ messages in thread
From: Vesa Jääskeläinen @ 2019-01-01 13:45 UTC (permalink / raw)
  To: Dan Murphy, Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Hi All,

On 20/12/2018 14.40, Vesa Jääskeläinen wrote:
> Idea was to define preset colors in device tree as an example when you 
> are dealing with multi-color LEDs without PWM. In that case you only 
> have GPIOs to control and then have a problem what does those GPIO's mean.
> 
> With preset definitions one can use color names to act as a shortcut to 
> configure GPIO's to proper state for that particular color.
> 
> For more flexible setups where you have PWM or such control you have 
> larger space of available colors. In this case you need to somehow 
> define also meaning of those controls.
> 
> Also we may not have LED with only red, green and blue elements. There 
> might in example be amber, ultraviolet, white elements.
> 
> This is where device tree is concerned. It helps us craft the logical 
> definition for LED so that we can control it from user space in common way.
> 
> Now the next problem then is how does user space work then.
> 
> For multi-color LEDs it it important to change the color atomically so 
> that no wrong colors are being shown as user space got interrupted when 
> controlling it.
> 
> Also we have brightness setting that would be useful for PWM controlled 
> LEDs.
> 
> Setting color is easy when you use preset names then you only need to 
> deal with brightness value (eg. RGB -> HSV * brightness -> RGB). Of 
> course here additional problem is other color elements are they then 
> scaled according to brightness value?.
> 
> Setting color as "raw" values is then next problem. In order to do it 
> atomically it needs to be one atomic activation and could be eg. one 
> write to "color" sysfs entry with combination of all color elements and 
> perhaps additionally also brightness value. Next question is then what 
> is the format for such entry then? What are the value ranges? In here we 
> can utilize device tree definition to help define what kind of LED we do 
> have and what kind of capabilities it does have.
> 
> Additional problem risen also in discussion was non-linearity of some 
> control mechanisms vs. perceived color. So there might be a need for 
> curve mapping similarly what is with backlight control and that would be 
> defined either in device tree and possibly in user space if there is a 
> need for that. I suppose golden curve definition in device tree should 
> be good enough.
> 
> Then there was additional discussion about possible animation support 
> but I would leave that for future design as that would then be utilizing 
> the same framework.
> 
> I suppose color space handling and that kind of stuff should be in some 
> led core functionality and then raw control should be part of physical 
> led driver.
> 
> I was planning to play with it during holiday season but lets see how it 
> goes. Feel free to also experiment with the idea.

I was playing with this and got some results with PWM LED driver. I 
would like to get feedback now even thou it is not yet ready for patch 
sending.

They still need more work but the idea can be seen here:
https://github.com/vesajaaskelainen/linux/tree/wip-multi-color-led

This branch is now based on Linux kernel 4.20 release.

Consider that branch as volatile as I will forcibly update it when there 
are updates.

 From there specifically in commits (while they last):

drivers: leds: Add core support for multi color element LEDs
https://github.com/vesajaaskelainen/linux/commit/55d553906d0a158591435bb6323a318462079d59

WIP: drivers: leds: leds-pwm: Add multi color element LED support.
https://github.com/vesajaaskelainen/linux/commit/efccef08cbf3b2e1e49b95b69ff81cd380519fe3

What is there now:

- led-core supports color elements
- led-class supports users space configuration
- both led-core and led-class are driver agnostic so they should be 
treated as generic code.
- leds-pwm: my testing code with PWM led.
- no HSV support for brightness as there could be multiple color 
elements out from traditional red-green-blue space or odd combinations 
of colors and they are a bit hard to map to HSV formula (and it needs 
fixed point math).
- no color presets that could be optionally be selected
- when I configure led trigger to heartbeat it actually blinks with 
color specified -- thou trigger gets zeroed out with one sets new color 
or brightness as that was previous functionality with brightness.
- some documentation added
- code should pass checkpatch

What I was planning to do next:

- cleanup PWM LED driver so that it works with and without 
LED_MULTI_COLOR_LED being defined.
- improve documentation
- try out how my other device behaves which have dual color element LED 
controlled with GPIO's and see how it would integrate to gpio-led driver.

I would like to get feedback on:
- Device tree idea
- Internal logic
- Should the trigger be really reseted when one changes value of 
brightness? I would think it should function like setting brightness 
entry from sysfs would set current brightness for trigger when it is 
lit. Setting color should change color and brightness and it should be 
active from there one until trigger is disabled from trigger sysfs node.

My testing device has RGB LED with all color elements controlled with 
individual PWM channels from TI's AM335x's integrated PWM controller.

In device tree I have following:

	multi-color-leds {
		compatible = "pwm-leds";

		status-led {
			label = "status";

			element-red {
				pwms = <&ehrpwm0 0 100000 0>;
			};
			element-green {
				pwms = <&ehrpwm1 0 100000 0>;
			};
			element-blue {
				pwms = <&ehrpwm1 1 100000 0>;
			};
		};
	};

For my second test device I was planning to replace "pwms" with "gpios" 
or such entries.

In user space one can use it like:

# --- start of snippet ---

hostname ~ # cd /sys/class/leds/
hostname leds # ls
status
hostname leds # cd status
hostname status # ls
brightness      color           device          max_brightness 
max_color       power           subsystem       trigger         uevent
hostname status # cat color
brightness=0 red=0 green=0 blue=0

# some notes about color value here.
# - red, green, and blue are directly coming from device tree
# definition. if one would add eg. element-white or element-uv entries
# then they would appear here as well.
# - brightness is hardcoded entry

hostname status # cat max_color
brightness=255 red=255 green=255 blue=255
hostname status # cat brightness
0
hostname status # cat max_brightness
255

# Set color and brightness to maximum values eg. "white"
hostname status # cat max_color > color

# Zero out red and green elements to make color blue
hostname status # echo "red=0 green=0" > color

# Configure individual color elements
hostname status # echo "red=55 green=22 blue=11" > color

# Start with max brightness and then dim it with each step
hostname status # echo 255 > brightness
hostname status # echo 128 > brightness
hostname status # echo 32 > brightness

# And finally with brightness=0 LED is OFF
hostname status # echo 0 > brightness

# --- end of snippet ---

About color presets...

I believe the optional color preset thing could work like:

	multi-color-leds {
		compatible = "pwm-leds";

		status-led {
			label = "status";

			element-red {
				pwms = <&ehrpwm0 0 100000 0>;
			};
			element-green {
				pwms = <&ehrpwm1 0 100000 0>;
			};
			element-blue {
				pwms = <&ehrpwm1 1 100000 0>;
			};

			color-orange = 255,128,0;
		};
	};

Then in user space:

hostname status # echo "orange" > color

or with combined brightness:

hostname status # echo "brightness=255 orange" > color

But then again -- I am a bit unsure here myself is it a good idea. I 
need to try out how the dual color element GPIO LED variant works first. 
My current hunch is that we might not need the color presets as one can 
now set all color elements in one go. It just changes a bit logic how it 
is used.

With dual color element LED with GPIO control it might as well be:

# for orange:
echo "brightness=255 red=255 green=128" > color
# or max value as GPIO led doesn't really care:
echo "brightness=255 red=255 green=255" > color

# for red:
echo "brightness=255 red=255 green=0" > color

# for green:
echo "brightness=255 red=0 green=255" > color

# for off:
echo "brightness=0" > color
# or
echo 0 > brightness

Thanks,
Vesa Jääskeläinen

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-31 16:28                               ` Pavel Machek
@ 2019-01-01 14:26                                 ` Jacek Anaszewski
  0 siblings, 0 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-01 14:26 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

Hi Pavel,

On 12/31/18 5:28 PM, Pavel Machek wrote:
> Hi!
> 
>>>>>> There is still HSV approach [0] in store. One problem with proposed
>>>>>> implementation is fixed algorithm of RGB <-> HSV color space conversion.
>>>>>> Maybe allowing for some board specific adjustments in DT would add
>>>>>> more flexibility.
>>>>>>
>>>>>> [0] https://lkml.org/lkml/2017/8/31/255
>>>>>
>>>>> Yes we could do HSV. Problem is that that we do not really have RGB
>>>>> available. We do have integers for red, green and blue, but they do
>>>>> not correspond to RGB colorspace.
>>>>
>>>> OK, so conversion from HSV to RGB would only increase the aberration.
>>>> So, let's stick to RGB - we've got to have some stable ground and this
>>>> is something that the hardware at least pretends to be compliant
>>>> with.
>>>
>>> I'm not saying that we should stick to RGB. I'm just saying that
>>> problem is complex.
>>>
>>> And no, hardware does not even pretend to be compliant with RGB color
>>> model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
>>> particular, in RGB there is non-linear brightness curve.
>>
>> Quotation from the wiki page you referred to:
>>
>> "RGB is a device-dependent color model: different devices detect or
>> reproduce a given RGB value differently, since the color elements (such
>> as phosphors or dyes) and their response to the individual R, G, and B
>> levels vary from manufacturer to manufacturer, or even in the same
>> device over time. Thus an RGB value does not define the same color
>> across devices without some kind of color management"
>>
>> This claim alone leaves much room for the manufacturers to pretend that
>> their devices are compliant with RGB model.
> 
> Much room, but everyone agrees that R=G=B=255 should be some kind of
> white, and what other colors "approximately" mean.
> 
> I have two monitors, and no, colors don't match.
> 
> Do you have access to RGB led? Try to compare two monitors, and then
> RGB led with monitor. RGB led will be _way_ off.
> 
> This chart makes sense:
> 
> https://www.rapidtables.com/web/color/RGB_Color.html
> 
> Try it on your LED device...
> 
>>> I believe problem to start with is the "white" problem. Setting
>>> R=G=B=255 will _not_ result in anything close to white light on
>>> hardware I have.
>>
>> RGBW LED controllers solve this problem. For the devices without
>> white/amber we cannot do more than the hardware allows for.
> 
> But the hardware can do some kind of white. It is just that R=G=B=255
> will result in green-ish-blue and something like R=255, G=50, B=10 is
> neccessary to get approximation of white.
> 
> IMO good start would be to specify what kind of intensities are
> neccessary to approximate white. And then try converting from RGB to
> led intensities, and see if it somehow works.

I don't have access to RGB LED, and unfortunately have lack of time
currently to play with it even if I had one.

In order to gain a full understanding of your idea of RGB to LED
intensity conversion, we'd need to see the full algorithm.

It feels like imposing some restrictions on user regarding
the available scope of colors to set.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-31 19:15                                 ` Dan Murphy
@ 2019-01-01 14:42                                   ` Jacek Anaszewski
  2019-01-01 18:11                                     ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-01 14:42 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek; +Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 12/31/18 8:15 PM, Dan Murphy wrote:
> On 12/31/18 9:47 AM, Jacek Anaszewski wrote:
>> On 12/31/18 4:43 PM, Jacek Anaszewski wrote:
>>> On 12/30/18 6:35 PM, Pavel Machek wrote:
>>>> On Sun 2018-12-30 18:09:35, Jacek Anaszewski wrote:
>>>>> On 12/29/18 8:07 PM, Pavel Machek wrote:
>>>>>> Hi!
>>>>>>
>>>>>>>>> With the "color" sysfs file it will make more sense to allow for user
>>>>>>>>> defined color palettes.
>>>>>>>>>
>>>>>>>>
>>>>>>>> I think defining these values in the device tree or acpi severely limits the devices
>>>>>>>> capabilities.  Especially in development phases.  If the knobs were exposed then the user space
>>>>>>>> can create new experiences.  The color definition should be an absolute color defined in the dt and
>>>>>>>> either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
>>>>>>>> of the user experience and the dt/acpi needs to set the capabilities.
>>>>>>>>
>>>>>>>> I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
>>>>>>>>
>>>>>>>> Maybe the framework could take these groups and combine/group them into a single node with the groups colors.
>>>>>>>
>>>>>>> There is still HSV approach [0] in store. One problem with proposed
>>>>>>> implementation is fixed algorithm of RGB <-> HSV color space conversion.
>>>>>>> Maybe allowing for some board specific adjustments in DT would add
>>>>>>> more flexibility.
>>>>>>>
>>>>>>> [0] https://lkml.org/lkml/2017/8/31/255
>>>>>>
>>>>>> Yes we could do HSV. Problem is that that we do not really have RGB
>>>>>> available. We do have integers for red, green and blue, but they do
>>>>>> not correspond to RGB colorspace.
>>>>>
>>>>> OK, so conversion from HSV to RGB would only increase the aberration.
>>>>> So, let's stick to RGB - we've got to have some stable ground and this
>>>>> is something that the hardware at least pretends to be compliant
>>>>> with.
>>>>
>>>> I'm not saying that we should stick to RGB. I'm just saying that
>>>> problem is complex.
>>>>
>>>> And no, hardware does not even pretend to be compliant with RGB color
>>>> model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
>>>> particular, in RGB there is non-linear brightness curve.
>>>
>>> Quotation from the wiki page you referred to:
>>>
>>> "RGB is a device-dependent color model: different devices detect or
>>> reproduce a given RGB value differently, since the color elements (such
>>> as phosphors or dyes) and their response to the individual R, G, and B
>>> levels vary from manufacturer to manufacturer, or even in the same
>>> device over time. Thus an RGB value does not define the same color
>>> across devices without some kind of color management"
>>>
>>> This claim alone leaves much room for the manufacturers to pretend that
>>> their devices are compliant with RGB model.
>>>
>>> And the documentation of the hardware the discussed driver is for
>>> also refers to RGB model in many places - e.g. see Table 1, page 15
>>> in the document [0], where mapping of output triplets to an RGB module
>>> is shown.
>>>
>>> One thing that I missed is that the discussed hardware provides
>>> LEDn_BRIGHTNESS registers for each RGB LED module, that can be
>>> configured to set color intensity in linear or logarithmic fashion.
>>>
>>> Actually this stands in contradiction with RGB model, since
>>> change of "color intensity" means change of all RGB components.
>>>
>>> We could use brightness file as for monochrome LEDs for that,
>>
>> Here I mean brightness file in addition to the previously proposed
>> red, green and blue files.
>>
>>> but we'd need to come up with consistent interface semantics
>>> for all devices, also those which don't have corresponding
>>> functionality. Probably this is the place where we could apply
>>> some RGB<->HSV conversion, as color intensity feels something
>>> more of HSV's saturation and value.
>>>
>>> It would be good to hear from Dan how that looks in reality
>>> in case of lp5024 device.
> 
> Sorry for the non-response I have had a passing in my family and have not been at my
> computer for some time.

Sorry to hear that. In fact there was no delay, since I wrote that
yesterday.

> I am not seeing how HSV will fit into this device.  Not sure what the V is in HSV.
I meant RGB<->HSV conversion as a fallback for RGB LED
controllers that don't have the functionality similar to
LEDn_BRIGHTNESS. For lp5024 we'd use just what hardware offers.

You can get the flavor of the relationship between RGB and HSV using
e.g. GIMP color editor. After that you could share a feedback if
changing LEDn_BRIGHTNESS feels like changing saturation and value of
HSV.

Remember that we're still talking about generic approach to the problem.

> I am still not a fan of defining colors in the kernel.  I think the user space needs to do this based
> on information it is given.  When I look at Android the user space sets all the policies of the hardware
> the kernel just provides the vehicle to hardware.  I think defining any set colors in the kernel for devices
> that have a full color spectrum palette is very restricting.  The kernel should indicate the absolute colors
> available and not the colors that are allowed.  So in this case we indicate that a Red, green and blue LED are
> available or that the palette is variable.  Or in the case of a white LED driver we just say white.

HSV is in no way restrictive. But I'm not pushing for that.
Vesa in his recent message mentions some difficulties in mapping all RGB
combinations to HSV.

We just need something generic and don't want ledn_mix and
ctrl_bank*mix sysfs files, which are device specific.

> In the case of this device there are RGB outputs that are grouped in clusters and controlled by the LEDn_BRIGHTNESS
> register.  This is what the brightness file is mapped to.  Within that cluster the individual intensity of the RGB can
> be modified via the OUTn_color register.  Not knowing what color LED is on what output means the sysfs node has to be left generic.
> 
> So as Pavel pointed out white would need to be achieved through the RGB individual LEDs being set to certain values and
> the difuser disfusing the light to achieve the color.  This was done on the original DROID device with a RGB and we
> were able to get a "white" color but had to set the RGB LEDs to different values.  For this device, once the color is
> achieved there may be no reason to adjust the color so adjusting the overall brightness of the LEDs without adjusting the
> individual color can be done with a single write and look seamless to the user.
> Or other colors can be tuned by setting the unneeded colors in the OUTn_color to 0.
> 
> These RGB LED clusters can also be grouped into LED banks as well so that all LEDs of the same color within the group will have
> the same color gradient and brightness.  This is achieved with the BANK_X_COLOR and BRIGHTNESS registers.
> 
> Again I am not sure how the HSV would work for this device since there is no reason to create a node for each LED output.
> As the overall brightness of the cluster or bank is controlled by a single brightness file.

I think that you misunderstood me. I didn't mention creating
separate nodes for each LED output anywhere.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-01 14:42                                   ` Jacek Anaszewski
@ 2019-01-01 18:11                                     ` Dan Murphy
  2019-01-01 22:06                                       ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-01 18:11 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Jacek

Thanks for the reply!

All

Happy New Year!

On 1/1/19 8:42 AM, Jacek Anaszewski wrote:
> On 12/31/18 8:15 PM, Dan Murphy wrote:
>> On 12/31/18 9:47 AM, Jacek Anaszewski wrote:
>>> On 12/31/18 4:43 PM, Jacek Anaszewski wrote:
>>>> On 12/30/18 6:35 PM, Pavel Machek wrote:
>>>>> On Sun 2018-12-30 18:09:35, Jacek Anaszewski wrote:
>>>>>> On 12/29/18 8:07 PM, Pavel Machek wrote:
>>>>>>> Hi!
>>>>>>>
>>>>>>>>>> With the "color" sysfs file it will make more sense to allow for user
>>>>>>>>>> defined color palettes.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I think defining these values in the device tree or acpi severely limits the devices
>>>>>>>>> capabilities.  Especially in development phases.  If the knobs were exposed then the user space
>>>>>>>>> can create new experiences.  The color definition should be an absolute color defined in the dt and
>>>>>>>>> either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
>>>>>>>>> of the user experience and the dt/acpi needs to set the capabilities.
>>>>>>>>>
>>>>>>>>> I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
>>>>>>>>>
>>>>>>>>> Maybe the framework could take these groups and combine/group them into a single node with the groups colors.
>>>>>>>>
>>>>>>>> There is still HSV approach [0] in store. One problem with proposed
>>>>>>>> implementation is fixed algorithm of RGB <-> HSV color space conversion.
>>>>>>>> Maybe allowing for some board specific adjustments in DT would add
>>>>>>>> more flexibility.
>>>>>>>>
>>>>>>>> [0] https://lkml.org/lkml/2017/8/31/255
>>>>>>>
>>>>>>> Yes we could do HSV. Problem is that that we do not really have RGB
>>>>>>> available. We do have integers for red, green and blue, but they do
>>>>>>> not correspond to RGB colorspace.
>>>>>>
>>>>>> OK, so conversion from HSV to RGB would only increase the aberration.
>>>>>> So, let's stick to RGB - we've got to have some stable ground and this
>>>>>> is something that the hardware at least pretends to be compliant
>>>>>> with.
>>>>>
>>>>> I'm not saying that we should stick to RGB. I'm just saying that
>>>>> problem is complex.
>>>>>
>>>>> And no, hardware does not even pretend to be compliant with RGB color
>>>>> model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
>>>>> particular, in RGB there is non-linear brightness curve.
>>>>
>>>> Quotation from the wiki page you referred to:
>>>>
>>>> "RGB is a device-dependent color model: different devices detect or
>>>> reproduce a given RGB value differently, since the color elements (such
>>>> as phosphors or dyes) and their response to the individual R, G, and B
>>>> levels vary from manufacturer to manufacturer, or even in the same
>>>> device over time. Thus an RGB value does not define the same color
>>>> across devices without some kind of color management"
>>>>
>>>> This claim alone leaves much room for the manufacturers to pretend that
>>>> their devices are compliant with RGB model.
>>>>
>>>> And the documentation of the hardware the discussed driver is for
>>>> also refers to RGB model in many places - e.g. see Table 1, page 15
>>>> in the document [0], where mapping of output triplets to an RGB module
>>>> is shown.
>>>>
>>>> One thing that I missed is that the discussed hardware provides
>>>> LEDn_BRIGHTNESS registers for each RGB LED module, that can be
>>>> configured to set color intensity in linear or logarithmic fashion.
>>>>
>>>> Actually this stands in contradiction with RGB model, since
>>>> change of "color intensity" means change of all RGB components.
>>>>
>>>> We could use brightness file as for monochrome LEDs for that,
>>>
>>> Here I mean brightness file in addition to the previously proposed
>>> red, green and blue files.
>>>
>>>> but we'd need to come up with consistent interface semantics
>>>> for all devices, also those which don't have corresponding
>>>> functionality. Probably this is the place where we could apply
>>>> some RGB<->HSV conversion, as color intensity feels something
>>>> more of HSV's saturation and value.
>>>>
>>>> It would be good to hear from Dan how that looks in reality
>>>> in case of lp5024 device.
>>
>> Sorry for the non-response I have had a passing in my family and have not been at my
>> computer for some time.
> 
> Sorry to hear that. In fact there was no delay, since I wrote that
> yesterday.
> 
>> I am not seeing how HSV will fit into this device.  Not sure what the V is in HSV.
> I meant RGB<->HSV conversion as a fallback for RGB LED
> controllers that don't have the functionality similar to
> LEDn_BRIGHTNESS. For lp5024 we'd use just what hardware offers.
> 
> You can get the flavor of the relationship between RGB and HSV using
> e.g. GIMP color editor. After that you could share a feedback if
> changing LEDn_BRIGHTNESS feels like changing saturation and value of
> HSV.
> 
> Remember that we're still talking about generic approach to the problem.
> 
>> I am still not a fan of defining colors in the kernel.  I think the user space needs to do this based
>> on information it is given.  When I look at Android the user space sets all the policies of the hardware
>> the kernel just provides the vehicle to hardware.  I think defining any set colors in the kernel for devices
>> that have a full color spectrum palette is very restricting.  The kernel should indicate the absolute colors
>> available and not the colors that are allowed.  So in this case we indicate that a Red, green and blue LED are
>> available or that the palette is variable.  Or in the case of a white LED driver we just say white.
> 
> HSV is in no way restrictive. But I'm not pushing for that.
> Vesa in his recent message mentions some difficulties in mapping all RGB
> combinations to HSV.
> 
> We just need something generic and don't want ledn_mix and
> ctrl_bank*mix sysfs files, which are device specific.

OK that makes sense.  I will have to think about how to map HSV to this device.  It becomes complex because
of the way this device groups the LEDs and has a single brightness control.  

If we had a version of the HSV->RGB framework that looks to be set for application then I can present a new version with that FW being used
on top of that patch?

Is that on linux-leds-next?


> 
>> In the case of this device there are RGB outputs that are grouped in clusters and controlled by the LEDn_BRIGHTNESS
>> register.  This is what the brightness file is mapped to.  Within that cluster the individual intensity of the RGB can
>> be modified via the OUTn_color register.  Not knowing what color LED is on what output means the sysfs node has to be left generic.
>>
>> So as Pavel pointed out white would need to be achieved through the RGB individual LEDs being set to certain values and
>> the difuser disfusing the light to achieve the color.  This was done on the original DROID device with a RGB and we
>> were able to get a "white" color but had to set the RGB LEDs to different values.  For this device, once the color is
>> achieved there may be no reason to adjust the color so adjusting the overall brightness of the LEDs without adjusting the
>> individual color can be done with a single write and look seamless to the user.
>> Or other colors can be tuned by setting the unneeded colors in the OUTn_color to 0.
>>
>> These RGB LED clusters can also be grouped into LED banks as well so that all LEDs of the same color within the group will have
>> the same color gradient and brightness.  This is achieved with the BANK_X_COLOR and BRIGHTNESS registers.
>>
>> Again I am not sure how the HSV would work for this device since there is no reason to create a node for each LED output.
>> As the overall brightness of the cluster or bank is controlled by a single brightness file.
> 
> I think that you misunderstood me. I didn't mention creating
> separate nodes for each LED output anywhere.
> 

No this was not something you indicated it was an earlier comment by Pavel, and it is which the LED file nodes are expected
as we have discussed in the past.

Dan
-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-01 18:11                                     ` Dan Murphy
@ 2019-01-01 22:06                                       ` Jacek Anaszewski
  0 siblings, 0 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-01 22:06 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek; +Cc: robh+dt, devicetree, linux-kernel, linux-leds

On 1/1/19 7:11 PM, Dan Murphy wrote:
> Jacek
> 
> Thanks for the reply!
> 
> All
> 
> Happy New Year!

Happy New Year!

> On 1/1/19 8:42 AM, Jacek Anaszewski wrote:
>> On 12/31/18 8:15 PM, Dan Murphy wrote:
>>> On 12/31/18 9:47 AM, Jacek Anaszewski wrote:
>>>> On 12/31/18 4:43 PM, Jacek Anaszewski wrote:
>>>>> On 12/30/18 6:35 PM, Pavel Machek wrote:
>>>>>> On Sun 2018-12-30 18:09:35, Jacek Anaszewski wrote:
>>>>>>> On 12/29/18 8:07 PM, Pavel Machek wrote:
>>>>>>>> Hi!
>>>>>>>>
>>>>>>>>>>> With the "color" sysfs file it will make more sense to allow for user
>>>>>>>>>>> defined color palettes.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I think defining these values in the device tree or acpi severely limits the devices
>>>>>>>>>> capabilities.  Especially in development phases.  If the knobs were exposed then the user space
>>>>>>>>>> can create new experiences.  The color definition should be an absolute color defined in the dt and
>>>>>>>>>> either the framework or user space needs to mix these appropriately.  IMO user space should set the policy
>>>>>>>>>> of the user experience and the dt/acpi needs to set the capabilities.
>>>>>>>>>>
>>>>>>>>>> I do like Pavels idea on defining the more standard binding pattern to "group" leds into a single group.
>>>>>>>>>>
>>>>>>>>>> Maybe the framework could take these groups and combine/group them into a single node with the groups colors.
>>>>>>>>>
>>>>>>>>> There is still HSV approach [0] in store. One problem with proposed
>>>>>>>>> implementation is fixed algorithm of RGB <-> HSV color space conversion.
>>>>>>>>> Maybe allowing for some board specific adjustments in DT would add
>>>>>>>>> more flexibility.
>>>>>>>>>
>>>>>>>>> [0] https://lkml.org/lkml/2017/8/31/255
>>>>>>>>
>>>>>>>> Yes we could do HSV. Problem is that that we do not really have RGB
>>>>>>>> available. We do have integers for red, green and blue, but they do
>>>>>>>> not correspond to RGB colorspace.
>>>>>>>
>>>>>>> OK, so conversion from HSV to RGB would only increase the aberration.
>>>>>>> So, let's stick to RGB - we've got to have some stable ground and this
>>>>>>> is something that the hardware at least pretends to be compliant
>>>>>>> with.
>>>>>>
>>>>>> I'm not saying that we should stick to RGB. I'm just saying that
>>>>>> problem is complex.
>>>>>>
>>>>>> And no, hardware does not even pretend to be compliant with RGB color
>>>>>> model ( https://en.wikipedia.org/wiki/RGB_color_model ). In
>>>>>> particular, in RGB there is non-linear brightness curve.
>>>>>
>>>>> Quotation from the wiki page you referred to:
>>>>>
>>>>> "RGB is a device-dependent color model: different devices detect or
>>>>> reproduce a given RGB value differently, since the color elements (such
>>>>> as phosphors or dyes) and their response to the individual R, G, and B
>>>>> levels vary from manufacturer to manufacturer, or even in the same
>>>>> device over time. Thus an RGB value does not define the same color
>>>>> across devices without some kind of color management"
>>>>>
>>>>> This claim alone leaves much room for the manufacturers to pretend that
>>>>> their devices are compliant with RGB model.
>>>>>
>>>>> And the documentation of the hardware the discussed driver is for
>>>>> also refers to RGB model in many places - e.g. see Table 1, page 15
>>>>> in the document [0], where mapping of output triplets to an RGB module
>>>>> is shown.
>>>>>
>>>>> One thing that I missed is that the discussed hardware provides
>>>>> LEDn_BRIGHTNESS registers for each RGB LED module, that can be
>>>>> configured to set color intensity in linear or logarithmic fashion.
>>>>>
>>>>> Actually this stands in contradiction with RGB model, since
>>>>> change of "color intensity" means change of all RGB components.
>>>>>
>>>>> We could use brightness file as for monochrome LEDs for that,
>>>>
>>>> Here I mean brightness file in addition to the previously proposed
>>>> red, green and blue files.
>>>>
>>>>> but we'd need to come up with consistent interface semantics
>>>>> for all devices, also those which don't have corresponding
>>>>> functionality. Probably this is the place where we could apply
>>>>> some RGB<->HSV conversion, as color intensity feels something
>>>>> more of HSV's saturation and value.
>>>>>
>>>>> It would be good to hear from Dan how that looks in reality
>>>>> in case of lp5024 device.
>>>
>>> Sorry for the non-response I have had a passing in my family and have not been at my
>>> computer for some time.
>>
>> Sorry to hear that. In fact there was no delay, since I wrote that
>> yesterday.
>>
>>> I am not seeing how HSV will fit into this device.  Not sure what the V is in HSV.
>> I meant RGB<->HSV conversion as a fallback for RGB LED
>> controllers that don't have the functionality similar to
>> LEDn_BRIGHTNESS. For lp5024 we'd use just what hardware offers.
>>
>> You can get the flavor of the relationship between RGB and HSV using
>> e.g. GIMP color editor. After that you could share a feedback if
>> changing LEDn_BRIGHTNESS feels like changing saturation and value of
>> HSV.
>>
>> Remember that we're still talking about generic approach to the problem.
>>
>>> I am still not a fan of defining colors in the kernel.  I think the user space needs to do this based
>>> on information it is given.  When I look at Android the user space sets all the policies of the hardware
>>> the kernel just provides the vehicle to hardware.  I think defining any set colors in the kernel for devices
>>> that have a full color spectrum palette is very restricting.  The kernel should indicate the absolute colors
>>> available and not the colors that are allowed.  So in this case we indicate that a Red, green and blue LED are
>>> available or that the palette is variable.  Or in the case of a white LED driver we just say white.
>>
>> HSV is in no way restrictive. But I'm not pushing for that.
>> Vesa in his recent message mentions some difficulties in mapping all RGB
>> combinations to HSV.
>>
>> We just need something generic and don't want ledn_mix and
>> ctrl_bank*mix sysfs files, which are device specific.
> 
> OK that makes sense.  I will have to think about how to map HSV to this device.  It becomes complex because
> of the way this device groups the LEDs and has a single brightness control.

I got back to the HSV idea only because of this LEDn_BRIGHTNESS feature
of lp5024. If it maps easily to S and V components of HSV then we would
have this conversion for free for this device.

Generally increasing S and V for given hue (H) results in going
from grayish to more saturated version of the same hue, where
the greater V, the greater "lightness".

Of course we would have to make some research to compare if other RGB
LED controllers available on the market approach this similarly.

> 
> If we had a version of the HSV->RGB framework that looks to be set for application then I can present a new version with that FW being used
> on top of that patch?
> 
> Is that on linux-leds-next?

We have older attempt on devel branch of linux-leds.git and a newer
one by Pavel I gave a pointer to in one of previous messages in this
thread. But please hold on for a while until we agree on that.

There is also recent proposal from Vesa Jääskeläinen, but I haven't
analyzed it in detail yet.

>>> In the case of this device there are RGB outputs that are grouped in clusters and controlled by the LEDn_BRIGHTNESS
>>> register.  This is what the brightness file is mapped to.  Within that cluster the individual intensity of the RGB can
>>> be modified via the OUTn_color register.  Not knowing what color LED is on what output means the sysfs node has to be left generic.
>>>
>>> So as Pavel pointed out white would need to be achieved through the RGB individual LEDs being set to certain values and
>>> the difuser disfusing the light to achieve the color.  This was done on the original DROID device with a RGB and we
>>> were able to get a "white" color but had to set the RGB LEDs to different values.  For this device, once the color is
>>> achieved there may be no reason to adjust the color so adjusting the overall brightness of the LEDs without adjusting the
>>> individual color can be done with a single write and look seamless to the user.
>>> Or other colors can be tuned by setting the unneeded colors in the OUTn_color to 0.
>>>
>>> These RGB LED clusters can also be grouped into LED banks as well so that all LEDs of the same color within the group will have
>>> the same color gradient and brightness.  This is achieved with the BANK_X_COLOR and BRIGHTNESS registers.
>>>
>>> Again I am not sure how the HSV would work for this device since there is no reason to create a node for each LED output.
>>> As the overall brightness of the cluster or bank is controlled by a single brightness file.
>>
>> I think that you misunderstood me. I didn't mention creating
>> separate nodes for each LED output anywhere.
>>
> 
> No this was not something you indicated it was an earlier comment by Pavel, and it is which the LED file nodes are expected
> as we have discussed in the past.
> 
> Dan
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-01 13:45                 ` Vesa Jääskeläinen
@ 2019-01-03 22:05                   ` Jacek Anaszewski
  2019-01-03 23:19                     ` Vesa Jääskeläinen
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-03 22:05 UTC (permalink / raw)
  To: Vesa Jääskeläinen, Dan Murphy, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Hi Vesa,

Thank you for sharing your ideas.

Please find my comment below.

On 1/1/19 2:45 PM, Vesa Jääskeläinen wrote:
> Hi All,
> 
> On 20/12/2018 14.40, Vesa Jääskeläinen wrote:
>> Idea was to define preset colors in device tree as an example when you 
>> are dealing with multi-color LEDs without PWM. In that case you only 
>> have GPIOs to control and then have a problem what does those GPIO's 
>> mean.
>>
>> With preset definitions one can use color names to act as a shortcut 
>> to configure GPIO's to proper state for that particular color.
>>
>> For more flexible setups where you have PWM or such control you have 
>> larger space of available colors. In this case you need to somehow 
>> define also meaning of those controls.
>>
>> Also we may not have LED with only red, green and blue elements. There 
>> might in example be amber, ultraviolet, white elements.
>>
>> This is where device tree is concerned. It helps us craft the logical 
>> definition for LED so that we can control it from user space in common 
>> way.
>>
>> Now the next problem then is how does user space work then.
>>
>> For multi-color LEDs it it important to change the color atomically so 
>> that no wrong colors are being shown as user space got interrupted 
>> when controlling it.
>>
>> Also we have brightness setting that would be useful for PWM 
>> controlled LEDs.
>>
>> Setting color is easy when you use preset names then you only need to 
>> deal with brightness value (eg. RGB -> HSV * brightness -> RGB). Of 
>> course here additional problem is other color elements are they then 
>> scaled according to brightness value?.
>>
>> Setting color as "raw" values is then next problem. In order to do it 
>> atomically it needs to be one atomic activation and could be eg. one 
>> write to "color" sysfs entry with combination of all color elements 
>> and perhaps additionally also brightness value. Next question is then 
>> what is the format for such entry then? What are the value ranges? In 
>> here we can utilize device tree definition to help define what kind of 
>> LED we do have and what kind of capabilities it does have.
>>
>> Additional problem risen also in discussion was non-linearity of some 
>> control mechanisms vs. perceived color. So there might be a need for 
>> curve mapping similarly what is with backlight control and that would 
>> be defined either in device tree and possibly in user space if there 
>> is a need for that. I suppose golden curve definition in device tree 
>> should be good enough.
>>
>> Then there was additional discussion about possible animation support 
>> but I would leave that for future design as that would then be 
>> utilizing the same framework.
>>
>> I suppose color space handling and that kind of stuff should be in 
>> some led core functionality and then raw control should be part of 
>> physical led driver.
>>
>> I was planning to play with it during holiday season but lets see how 
>> it goes. Feel free to also experiment with the idea.
> 
> I was playing with this and got some results with PWM LED driver. I 
> would like to get feedback now even thou it is not yet ready for patch 
> sending.
> 
> They still need more work but the idea can be seen here:
> https://github.com/vesajaaskelainen/linux/tree/wip-multi-color-led
> 
> This branch is now based on Linux kernel 4.20 release.
> 
> Consider that branch as volatile as I will forcibly update it when there 
> are updates.
> 
>  From there specifically in commits (while they last):
> 
> drivers: leds: Add core support for multi color element LEDs
> https://github.com/vesajaaskelainen/linux/commit/55d553906d0a158591435bb6323a318462079d59 
> 
> 
> WIP: drivers: leds: leds-pwm: Add multi color element LED support.
> https://github.com/vesajaaskelainen/linux/commit/efccef08cbf3b2e1e49b95b69ff81cd380519fe3 
> 
> 
> What is there now:
> 
> - led-core supports color elements
> - led-class supports users space configuration
> - both led-core and led-class are driver agnostic so they should be 
> treated as generic code.
> - leds-pwm: my testing code with PWM led.
> - no HSV support for brightness as there could be multiple color 
> elements out from traditional red-green-blue space or odd combinations 
> of colors and they are a bit hard to map to HSV formula (and it needs 
> fixed point math).
> - no color presets that could be optionally be selected
> - when I configure led trigger to heartbeat it actually blinks with 
> color specified -- thou trigger gets zeroed out with one sets new color 
> or brightness as that was previous functionality with brightness.
> - some documentation added
> - code should pass checkpatch
> 
> What I was planning to do next:
> 
> - cleanup PWM LED driver so that it works with and without 
> LED_MULTI_COLOR_LED being defined.
> - improve documentation
> - try out how my other device behaves which have dual color element LED 
> controlled with GPIO's and see how it would integrate to gpio-led driver.
> 
> I would like to get feedback on:
> - Device tree idea
> - Internal logic
> - Should the trigger be really reseted when one changes value of 
> brightness? I would think it should function like setting brightness 
> entry from sysfs would set current brightness for trigger when it is 
> lit. Setting color should change color and brightness and it should be 
> active from there one until trigger is disabled from trigger sysfs node.
> 
> My testing device has RGB LED with all color elements controlled with 
> individual PWM channels from TI's AM335x's integrated PWM controller.
> 
> In device tree I have following:
> 
>      multi-color-leds {
>          compatible = "pwm-leds";
> 
>          status-led {
>              label = "status";
> 
>              element-red {
>                  pwms = <&ehrpwm0 0 100000 0>;
>              };
>              element-green {
>                  pwms = <&ehrpwm1 0 100000 0>;
>              };
>              element-blue {
>                  pwms = <&ehrpwm1 1 100000 0>;
>              };
>          };
>      };
> 
> For my second test device I was planning to replace "pwms" with "gpios" 
> or such entries.
> 
> In user space one can use it like:
> 
> # --- start of snippet ---
> 
> hostname ~ # cd /sys/class/leds/
> hostname leds # ls
> status
> hostname leds # cd status
> hostname status # ls
> brightness      color           device          max_brightness 
> max_color       power           subsystem       trigger         uevent
> hostname status # cat color
> brightness=0 red=0 green=0 blue=0

This breaks one-value-per-file sysfs rule.

Regarding led_scale_color_elements() - I checked it in GIMP and
the results are not satisfactory when increasing brightness.
Even if we managed to fix it, the result would not be guaranteed
to be the same across all devices.

This is still the same problem.

I have another proposal, being a mix of what has been discussed so far:

    RGB LED class will expose following files:
    a) available by default:
      - red, green, blue
        Writing any of these file will result in writing corresponding
        device register.
      - color_space: it would accept color space, e,g. "hsv", that would
                     have to be supported by LED RGB core; setting color
                     space would create relevant files, e.g. for hsv
                     hue. saturation, brightness, and remove default ones
                     other "color spaces" could be defined in DT as
                     proposed by Vesa; reading this file would print
                     available color spaces

    b) available conditionally:
      - brightness
       It will be exposed by devices that have hardware support for
       changing color brightness, like lp5024, or it will be made
       available after setting relevant color space, like "hsv", or
       other color presets defined in DT

I think it will be flexible enough to meet everyone's needs.

Current triggers would work only when brightness file is available.

This is ad hoc design so it can have some logical flaws.

Best regards,
Jacek Anaszewski

> 
> # some notes about color value here.
> # - red, green, and blue are directly coming from device tree
> # definition. if one would add eg. element-white or element-uv entries
> # then they would appear here as well.
> # - brightness is hardcoded entry
> 
> hostname status # cat max_color
> brightness=255 red=255 green=255 blue=255
> hostname status # cat brightness
> 0
> hostname status # cat max_brightness
> 255
> 
> # Set color and brightness to maximum values eg. "white"
> hostname status # cat max_color > color
> 
> # Zero out red and green elements to make color blue
> hostname status # echo "red=0 green=0" > color
> 
> # Configure individual color elements
> hostname status # echo "red=55 green=22 blue=11" > color
> 
> # Start with max brightness and then dim it with each step
> hostname status # echo 255 > brightness
> hostname status # echo 128 > brightness
> hostname status # echo 32 > brightness
> 
> # And finally with brightness=0 LED is OFF
> hostname status # echo 0 > brightness
> 
> # --- end of snippet ---
> 
> About color presets...
> 
> I believe the optional color preset thing could work like:
> 
>      multi-color-leds {
>          compatible = "pwm-leds";
> 
>          status-led {
>              label = "status";
> 
>              element-red {
>                  pwms = <&ehrpwm0 0 100000 0>;
>              };
>              element-green {
>                  pwms = <&ehrpwm1 0 100000 0>;
>              };
>              element-blue {
>                  pwms = <&ehrpwm1 1 100000 0>;
>              };
> 
>              color-orange = 255,128,0;
>          };
>      };
> 
> Then in user space:
> 
> hostname status # echo "orange" > color
> 
> or with combined brightness:
> 
> hostname status # echo "brightness=255 orange" > color
> 
> But then again -- I am a bit unsure here myself is it a good idea. I 
> need to try out how the dual color element GPIO LED variant works first. 
> My current hunch is that we might not need the color presets as one can 
> now set all color elements in one go. It just changes a bit logic how it 
> is used.
> 
> With dual color element LED with GPIO control it might as well be:
> 
> # for orange:
> echo "brightness=255 red=255 green=128" > color
> # or max value as GPIO led doesn't really care:
> echo "brightness=255 red=255 green=255" > color
> 
> # for red:
> echo "brightness=255 red=255 green=0" > color
> 
> # for green:
> echo "brightness=255 red=0 green=255" > color
> 
> # for off:
> echo "brightness=0" > color
> # or
> echo 0 > brightness
> 
> Thanks,
> Vesa Jääskeläinen
> 

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-03 22:05                   ` Jacek Anaszewski
@ 2019-01-03 23:19                     ` Vesa Jääskeläinen
  2019-01-03 23:34                       ` Pavel Machek
  2019-01-04 19:12                       ` Jacek Anaszewski
  0 siblings, 2 replies; 106+ messages in thread
From: Vesa Jääskeläinen @ 2019-01-03 23:19 UTC (permalink / raw)
  To: Jacek Anaszewski, Dan Murphy, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Hi Jacek,

Comments below.

On 04/01/2019 0.05, Jacek Anaszewski wrote:
> Hi Vesa,
> 
> Thank you for sharing your ideas.
> 
> Please find my comment below.
> 
> On 1/1/19 2:45 PM, Vesa Jääskeläinen wrote:
>> Hi All,
>>
>> On 20/12/2018 14.40, Vesa Jääskeläinen wrote:
>>> Idea was to define preset colors in device tree as an example when 
>>> you are dealing with multi-color LEDs without PWM. In that case you 
>>> only have GPIOs to control and then have a problem what does those 
>>> GPIO's mean.
>>>
>>> With preset definitions one can use color names to act as a shortcut 
>>> to configure GPIO's to proper state for that particular color.
>>>
>>> For more flexible setups where you have PWM or such control you have 
>>> larger space of available colors. In this case you need to somehow 
>>> define also meaning of those controls.
>>>
>>> Also we may not have LED with only red, green and blue elements. 
>>> There might in example be amber, ultraviolet, white elements.
>>>
>>> This is where device tree is concerned. It helps us craft the logical 
>>> definition for LED so that we can control it from user space in 
>>> common way.
>>>
>>> Now the next problem then is how does user space work then.
>>>
>>> For multi-color LEDs it it important to change the color atomically 
>>> so that no wrong colors are being shown as user space got interrupted 
>>> when controlling it.
>>>
>>> Also we have brightness setting that would be useful for PWM 
>>> controlled LEDs.
>>>
>>> Setting color is easy when you use preset names then you only need to 
>>> deal with brightness value (eg. RGB -> HSV * brightness -> RGB). Of 
>>> course here additional problem is other color elements are they then 
>>> scaled according to brightness value?.
>>>
>>> Setting color as "raw" values is then next problem. In order to do it 
>>> atomically it needs to be one atomic activation and could be eg. one 
>>> write to "color" sysfs entry with combination of all color elements 
>>> and perhaps additionally also brightness value. Next question is then 
>>> what is the format for such entry then? What are the value ranges? In 
>>> here we can utilize device tree definition to help define what kind 
>>> of LED we do have and what kind of capabilities it does have.
>>>
>>> Additional problem risen also in discussion was non-linearity of some 
>>> control mechanisms vs. perceived color. So there might be a need for 
>>> curve mapping similarly what is with backlight control and that would 
>>> be defined either in device tree and possibly in user space if there 
>>> is a need for that. I suppose golden curve definition in device tree 
>>> should be good enough.
>>>
>>> Then there was additional discussion about possible animation support 
>>> but I would leave that for future design as that would then be 
>>> utilizing the same framework.
>>>
>>> I suppose color space handling and that kind of stuff should be in 
>>> some led core functionality and then raw control should be part of 
>>> physical led driver.
>>>
>>> I was planning to play with it during holiday season but lets see how 
>>> it goes. Feel free to also experiment with the idea.
>>
>> I was playing with this and got some results with PWM LED driver. I 
>> would like to get feedback now even thou it is not yet ready for patch 
>> sending.
>>
>> They still need more work but the idea can be seen here:
>> https://github.com/vesajaaskelainen/linux/tree/wip-multi-color-led
>>
>> This branch is now based on Linux kernel 4.20 release.
>>
>> Consider that branch as volatile as I will forcibly update it when 
>> there are updates.
>>
>>  From there specifically in commits (while they last):
>>
>> drivers: leds: Add core support for multi color element LEDs
>> https://github.com/vesajaaskelainen/linux/commit/55d553906d0a158591435bb6323a318462079d59 
>>
>>
>> WIP: drivers: leds: leds-pwm: Add multi color element LED support.
>> https://github.com/vesajaaskelainen/linux/commit/efccef08cbf3b2e1e49b95b69ff81cd380519fe3 
>>
>>
>> What is there now:
>>
>> - led-core supports color elements
>> - led-class supports users space configuration
>> - both led-core and led-class are driver agnostic so they should be 
>> treated as generic code.
>> - leds-pwm: my testing code with PWM led.
>> - no HSV support for brightness as there could be multiple color 
>> elements out from traditional red-green-blue space or odd combinations 
>> of colors and they are a bit hard to map to HSV formula (and it needs 
>> fixed point math).
>> - no color presets that could be optionally be selected
>> - when I configure led trigger to heartbeat it actually blinks with 
>> color specified -- thou trigger gets zeroed out with one sets new 
>> color or brightness as that was previous functionality with brightness.
>> - some documentation added
>> - code should pass checkpatch
>>
>> What I was planning to do next:
>>
>> - cleanup PWM LED driver so that it works with and without 
>> LED_MULTI_COLOR_LED being defined.
>> - improve documentation
>> - try out how my other device behaves which have dual color element 
>> LED controlled with GPIO's and see how it would integrate to gpio-led 
>> driver.
>>
>> I would like to get feedback on:
>> - Device tree idea
>> - Internal logic
>> - Should the trigger be really reseted when one changes value of 
>> brightness? I would think it should function like setting brightness 
>> entry from sysfs would set current brightness for trigger when it is 
>> lit. Setting color should change color and brightness and it should be 
>> active from there one until trigger is disabled from trigger sysfs node.
>>
>> My testing device has RGB LED with all color elements controlled with 
>> individual PWM channels from TI's AM335x's integrated PWM controller.
>>
>> In device tree I have following:
>>
>>      multi-color-leds {
>>          compatible = "pwm-leds";
>>
>>          status-led {
>>              label = "status";
>>
>>              element-red {
>>                  pwms = <&ehrpwm0 0 100000 0>;
>>              };
>>              element-green {
>>                  pwms = <&ehrpwm1 0 100000 0>;
>>              };
>>              element-blue {
>>                  pwms = <&ehrpwm1 1 100000 0>;
>>              };
>>          };
>>      };
>>
>> For my second test device I was planning to replace "pwms" with 
>> "gpios" or such entries.
>>
>> In user space one can use it like:
>>
>> # --- start of snippet ---
>>
>> hostname ~ # cd /sys/class/leds/
>> hostname leds # ls
>> status
>> hostname leds # cd status
>> hostname status # ls
>> brightness      color           device          max_brightness 
>> max_color       power           subsystem       trigger         uevent
>> hostname status # cat color
>> brightness=0 red=0 green=0 blue=0
> 
> This breaks one-value-per-file sysfs rule.

I believe you are referring to this text in:
https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt

"Attributes should be ASCII text files, preferably with only one value
per file. It is noted that it may not be efficient to contain only one
value per file, so it is socially acceptable to express an array of
values of the same type."

I suppose if one would just make it an array of values (separated by 
space) and then one file with string array of color element names and on 
file with maximum value array it could be within those words.

The it would be something like:

$ echo "23 54 32" > color

$ cat max_color
255 255 255

$ cat color_names
red green blue

In addition to this -- one could also export individual color element files.

> Regarding led_scale_color_elements() - I checked it in GIMP and
> the results are not satisfactory when increasing brightness.
> Even if we managed to fix it, the result would not be guaranteed
> to be the same across all devices.

No and they will never be the same. I was told by our hardware expert 
that it is rather impossible to get linearly behaving LED control 
without special curve fitting trimmed for particular hardware and LED 
component in use. And if you go and change LED component/vendor it would 
need to be "calibrated" again if such accuracy would be required. Also 
LEDs age and that has also effect on this.
> This is still the same problem.
> 
> I have another proposal, being a mix of what has been discussed so far:
> 
>     RGB LED class will expose following files:
>     a) available by default:
>       - red, green, blue
>         Writing any of these file will result in writing corresponding
>         device register.

Problem with this is that we are basically back at square one and one 
cannot do "atomic" color change with this.

In order to set or activate new values one would need "load values" file 
or such that when writing to it would activate new values. However it 
becomes quite clumsy interface at that point as you need to handle 
multiple writes to multiple files and makes those operations rather slow.

Then we have color presets left that could kinda solve the issue on 
setting the color to fixed values atomically.

Of course one direction is what happened with gpio driver was own device 
node with ioctl's allowing more faster and more fancier control.

>       - color_space: it would accept color space, e,g. "hsv", that would
>                      have to be supported by LED RGB core; setting color
>                      space would create relevant files, e.g. for hsv
>                      hue. saturation, brightness, and remove default ones
>                      other "color spaces" could be defined in DT as
>                      proposed by Vesa; reading this file would print
>                      available color spaces
> 
>     b) available conditionally:
>       - brightness
>        It will be exposed by devices that have hardware support for
>        changing color brightness, like lp5024, or it will be made
>        available after setting relevant color space, like "hsv", or
>        other color presets defined in DT
> 
> I think it will be flexible enough to meet everyone's needs.
> 
> Current triggers would work only when brightness file is available.

Or we could transition it in that case to simulated "on/off" type of 
thing. As that is what triggers more or less use.

When "on" LED would have its configured color and when "off" LED would 
be turned off (eg. values of zero).

> This is ad hoc design so it can have some logical flaws.
> 
> Best regards,
> Jacek Anaszewski

Thanks,
Vesa Jääskeläinen

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-03 23:19                     ` Vesa Jääskeläinen
@ 2019-01-03 23:34                       ` Pavel Machek
  2019-01-04 19:49                         ` Vesa Jääskeläinen
  2019-01-04 19:12                       ` Jacek Anaszewski
  1 sibling, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2019-01-03 23:34 UTC (permalink / raw)
  To: Vesa Jääskeläinen
  Cc: Jacek Anaszewski, Dan Murphy, robh+dt, devicetree, linux-kernel,
	linux-leds

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

Hi!

> >Regarding led_scale_color_elements() - I checked it in GIMP and
> >the results are not satisfactory when increasing brightness.
> >Even if we managed to fix it, the result would not be guaranteed
> >to be the same across all devices.
> 
> No and they will never be the same. I was told by our hardware expert that
> it is rather impossible to get linearly behaving LED control without special
> curve fitting trimmed for particular hardware and LED component in use. And
> if you go and change LED component/vendor it would need to be "calibrated"
> again if such accuracy would be required. Also LEDs age and that has also
> effect on this.

Well, it is not possible to "perfectly" calibrate LCD monitors,
either. Yet, color tables make sense for them.

And we should aim for the same thing.

And yes, it may mean re-doing calibration when vendor changes. And it
will mean some math and some understanding of colors.

And... LEDs are linear-enough as it is. That is not a problem. But RGB
does _not_ expect linear response. That's why colors are _way_ off currently.

> >I have another proposal, being a mix of what has been discussed so far:
> >
> >    RGB LED class will expose following files:
> >    a) available by default:
> >      - red, green, blue
> >        Writing any of these file will result in writing corresponding
> >        device register.
> 
> Problem with this is that we are basically back at square one and one cannot
> do "atomic" color change with this.
> 
> In order to set or activate new values one would need "load values" file or
> such that when writing to it would activate new values. However it becomes
> quite clumsy interface at that point as you need to handle multiple writes
> to multiple files and makes those operations rather slow.

If you don't like the interface, create an shared library. It may be
neccessary, anyway, for the color operations.

You say it is "rather slow" to change all 3 colors. How long does it
take, and how long do you need it to take?

> Then we have color presets left that could kinda solve the issue on setting
> the color to fixed values atomically.

Lets not design crazy interface "because sysfs writing is too
slow". Hint: it is not. 
									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-03 23:19                     ` Vesa Jääskeläinen
  2019-01-03 23:34                       ` Pavel Machek
@ 2019-01-04 19:12                       ` Jacek Anaszewski
  2019-01-04 20:12                         ` Pavel Machek
  1 sibling, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-04 19:12 UTC (permalink / raw)
  To: Vesa Jääskeläinen, Dan Murphy, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Hi Vesa,

On 1/4/19 12:19 AM, Vesa Jääskeläinen wrote:
> Hi Jacek,
> 
> Comments below.
> 
> On 04/01/2019 0.05, Jacek Anaszewski wrote:
>> Hi Vesa,
>>
>> Thank you for sharing your ideas.
>>
>> Please find my comment below.
>>
>> On 1/1/19 2:45 PM, Vesa Jääskeläinen wrote:
>>> Hi All,
>>>
>>> On 20/12/2018 14.40, Vesa Jääskeläinen wrote:
>>>> Idea was to define preset colors in device tree as an example when 
>>>> you are dealing with multi-color LEDs without PWM. In that case you 
>>>> only have GPIOs to control and then have a problem what does those 
>>>> GPIO's mean.
>>>>
>>>> With preset definitions one can use color names to act as a shortcut 
>>>> to configure GPIO's to proper state for that particular color.
>>>>
>>>> For more flexible setups where you have PWM or such control you have 
>>>> larger space of available colors. In this case you need to somehow 
>>>> define also meaning of those controls.
>>>>
>>>> Also we may not have LED with only red, green and blue elements. 
>>>> There might in example be amber, ultraviolet, white elements.
>>>>
>>>> This is where device tree is concerned. It helps us craft the 
>>>> logical definition for LED so that we can control it from user space 
>>>> in common way.
>>>>
>>>> Now the next problem then is how does user space work then.
>>>>
>>>> For multi-color LEDs it it important to change the color atomically 
>>>> so that no wrong colors are being shown as user space got 
>>>> interrupted when controlling it.
>>>>
>>>> Also we have brightness setting that would be useful for PWM 
>>>> controlled LEDs.
>>>>
>>>> Setting color is easy when you use preset names then you only need 
>>>> to deal with brightness value (eg. RGB -> HSV * brightness -> RGB). 
>>>> Of course here additional problem is other color elements are they 
>>>> then scaled according to brightness value?.
>>>>
>>>> Setting color as "raw" values is then next problem. In order to do 
>>>> it atomically it needs to be one atomic activation and could be eg. 
>>>> one write to "color" sysfs entry with combination of all color 
>>>> elements and perhaps additionally also brightness value. Next 
>>>> question is then what is the format for such entry then? What are 
>>>> the value ranges? In here we can utilize device tree definition to 
>>>> help define what kind of LED we do have and what kind of 
>>>> capabilities it does have.
>>>>
>>>> Additional problem risen also in discussion was non-linearity of 
>>>> some control mechanisms vs. perceived color. So there might be a 
>>>> need for curve mapping similarly what is with backlight control and 
>>>> that would be defined either in device tree and possibly in user 
>>>> space if there is a need for that. I suppose golden curve definition 
>>>> in device tree should be good enough.
>>>>
>>>> Then there was additional discussion about possible animation 
>>>> support but I would leave that for future design as that would then 
>>>> be utilizing the same framework.
>>>>
>>>> I suppose color space handling and that kind of stuff should be in 
>>>> some led core functionality and then raw control should be part of 
>>>> physical led driver.
>>>>
>>>> I was planning to play with it during holiday season but lets see 
>>>> how it goes. Feel free to also experiment with the idea.
>>>
>>> I was playing with this and got some results with PWM LED driver. I 
>>> would like to get feedback now even thou it is not yet ready for 
>>> patch sending.
>>>
>>> They still need more work but the idea can be seen here:
>>> https://github.com/vesajaaskelainen/linux/tree/wip-multi-color-led
>>>
>>> This branch is now based on Linux kernel 4.20 release.
>>>
>>> Consider that branch as volatile as I will forcibly update it when 
>>> there are updates.
>>>
>>>  From there specifically in commits (while they last):
>>>
>>> drivers: leds: Add core support for multi color element LEDs
>>> https://github.com/vesajaaskelainen/linux/commit/55d553906d0a158591435bb6323a318462079d59 
>>>
>>>
>>> WIP: drivers: leds: leds-pwm: Add multi color element LED support.
>>> https://github.com/vesajaaskelainen/linux/commit/efccef08cbf3b2e1e49b95b69ff81cd380519fe3 
>>>
>>>
>>> What is there now:
>>>
>>> - led-core supports color elements
>>> - led-class supports users space configuration
>>> - both led-core and led-class are driver agnostic so they should be 
>>> treated as generic code.
>>> - leds-pwm: my testing code with PWM led.
>>> - no HSV support for brightness as there could be multiple color 
>>> elements out from traditional red-green-blue space or odd 
>>> combinations of colors and they are a bit hard to map to HSV formula 
>>> (and it needs fixed point math).
>>> - no color presets that could be optionally be selected
>>> - when I configure led trigger to heartbeat it actually blinks with 
>>> color specified -- thou trigger gets zeroed out with one sets new 
>>> color or brightness as that was previous functionality with brightness.
>>> - some documentation added
>>> - code should pass checkpatch
>>>
>>> What I was planning to do next:
>>>
>>> - cleanup PWM LED driver so that it works with and without 
>>> LED_MULTI_COLOR_LED being defined.
>>> - improve documentation
>>> - try out how my other device behaves which have dual color element 
>>> LED controlled with GPIO's and see how it would integrate to gpio-led 
>>> driver.
>>>
>>> I would like to get feedback on:
>>> - Device tree idea
>>> - Internal logic
>>> - Should the trigger be really reseted when one changes value of 
>>> brightness? I would think it should function like setting brightness 
>>> entry from sysfs would set current brightness for trigger when it is 
>>> lit. Setting color should change color and brightness and it should 
>>> be active from there one until trigger is disabled from trigger sysfs 
>>> node.
>>>
>>> My testing device has RGB LED with all color elements controlled with 
>>> individual PWM channels from TI's AM335x's integrated PWM controller.
>>>
>>> In device tree I have following:
>>>
>>>      multi-color-leds {
>>>          compatible = "pwm-leds";
>>>
>>>          status-led {
>>>              label = "status";
>>>
>>>              element-red {
>>>                  pwms = <&ehrpwm0 0 100000 0>;
>>>              };
>>>              element-green {
>>>                  pwms = <&ehrpwm1 0 100000 0>;
>>>              };
>>>              element-blue {
>>>                  pwms = <&ehrpwm1 1 100000 0>;
>>>              };
>>>          };
>>>      };
>>>
>>> For my second test device I was planning to replace "pwms" with 
>>> "gpios" or such entries.
>>>
>>> In user space one can use it like:
>>>
>>> # --- start of snippet ---
>>>
>>> hostname ~ # cd /sys/class/leds/
>>> hostname leds # ls
>>> status
>>> hostname leds # cd status
>>> hostname status # ls
>>> brightness      color           device          max_brightness 
>>> max_color       power           subsystem       trigger         uevent
>>> hostname status # cat color
>>> brightness=0 red=0 green=0 blue=0
>>
>> This breaks one-value-per-file sysfs rule.
> 
> I believe you are referring to this text in:
> https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt
> 
> "Attributes should be ASCII text files, preferably with only one value
> per file. It is noted that it may not be efficient to contain only one
> value per file, so it is socially acceptable to express an array of
> values of the same type."
> 
> I suppose if one would just make it an array of values (separated by 
> space) and then one file with string array of color element names and on 
> file with maximum value array it could be within those words.
> 
> The it would be something like:
> 
> $ echo "23 54 32" > color

Go ahead, but first convince Pavel, and then Greg :-)

I'd personally would not have much against, especially that the
list of values will not grow for that one like in case of old patch set
[0] where Pavel and Greg thwarted my similar attempt.

> $ cat max_color
> 255 255 255
> 
> $ cat color_names
> red green blue
> 
> In addition to this -- one could also export individual color element 
> files.
> 
>> Regarding led_scale_color_elements() - I checked it in GIMP and
>> the results are not satisfactory when increasing brightness.
>> Even if we managed to fix it, the result would not be guaranteed
>> to be the same across all devices.
> 
> No and they will never be the same. I was told by our hardware expert 
> that it is rather impossible to get linearly behaving LED control 
> without special curve fitting trimmed for particular hardware and LED 
> component in use. And if you go and change LED component/vendor it would 
> need to be "calibrated" again if such accuracy would be required. Also 
> LEDs age and that has also effect on this.
>> This is still the same problem.
>>
>> I have another proposal, being a mix of what has been discussed so far:
>>
>>     RGB LED class will expose following files:
>>     a) available by default:
>>       - red, green, blue
>>         Writing any of these file will result in writing corresponding
>>         device register.
> 
> Problem with this is that we are basically back at square one and one 
> cannot do "atomic" color change with this.
> 
> In order to set or activate new values one would need "load values" file 
> or such that when writing to it would activate new values. However it 
> becomes quite clumsy interface at that point as you need to handle 
> multiple writes to multiple files and makes those operations rather slow.
> 
> Then we have color presets left that could kinda solve the issue on 
> setting the color to fixed values atomically.

That's why I proposed "color_space" file that is also a part of my
proposed design below.

> Of course one direction is what happened with gpio driver was own device 
> node with ioctl's allowing more faster and more fancier control.
> 
>>       - color_space: it would accept color space, e,g. "hsv", that would
>>                      have to be supported by LED RGB core; setting color
>>                      space would create relevant files, e.g. for hsv
>>                      hue. saturation, brightness, and remove default ones
>>                      other "color spaces" could be defined in DT as
>>                      proposed by Vesa; reading this file would print
>>                      available color spaces
>>
>>     b) available conditionally:
>>       - brightness
>>        It will be exposed by devices that have hardware support for
>>        changing color brightness, like lp5024, or it will be made
>>        available after setting relevant color space, like "hsv", or
>>        other color presets defined in DT
>>
>> I think it will be flexible enough to meet everyone's needs.
>>
>> Current triggers would work only when brightness file is available.
> 
> Or we could transition it in that case to simulated "on/off" type of 
> thing. As that is what triggers more or less use.
> 
> When "on" LED would have its configured color and when "off" LED would 
> be turned off (eg. values of zero).

Yeah, it would be even better solution.

[0] https://www.spinics.net/lists/devicetree/msg69730.html

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-03 23:34                       ` Pavel Machek
@ 2019-01-04 19:49                         ` Vesa Jääskeläinen
  2019-01-04 20:43                           ` Pavel Machek
  0 siblings, 1 reply; 106+ messages in thread
From: Vesa Jääskeläinen @ 2019-01-04 19:49 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Jacek Anaszewski, Dan Murphy, robh+dt, devicetree, linux-kernel,
	linux-leds

Hi Pavel,

On 04/01/2019 1.34, Pavel Machek wrote:
> Hi!
> 
>>> Regarding led_scale_color_elements() - I checked it in GIMP and
>>> the results are not satisfactory when increasing brightness.
>>> Even if we managed to fix it, the result would not be guaranteed
>>> to be the same across all devices.
>>
>> No and they will never be the same. I was told by our hardware expert that
>> it is rather impossible to get linearly behaving LED control without special
>> curve fitting trimmed for particular hardware and LED component in use. And
>> if you go and change LED component/vendor it would need to be "calibrated"
>> again if such accuracy would be required. Also LEDs age and that has also
>> effect on this.
> 
> Well, it is not possible to "perfectly" calibrate LCD monitors,
> either. Yet, color tables make sense for them.
> 
> And we should aim for the same thing.
> 
> And yes, it may mean re-doing calibration when vendor changes. And it
> will mean some math and some understanding of colors.
> 
> And... LEDs are linear-enough as it is. That is not a problem. But RGB
> does _not_ expect linear response. That's why colors are _way_ off currently.

Example what I was given was some LEDs are off for let's say 20% of PWM 
linearity and then there is non-linear curve for PWM value vs. intensity 
(this was in context of white LCD backlight).

One case where we currently are interested in linear intensity is LCD 
background color. For that we have ramp defined in device tree. There 
would probably be simple fix to get that curve fitting to work better 
but let's keep that as another topic for now.

I was thinking that if we get "calibration" curve support in PWM LED 
brightness we could then just use that as one solution within kernel and 
let LCD PWM brightness support use same functionality from LED 
framework. (eg. LCD backlight would bind to PWM controlled mono color 
LED node)

Other case is that we need to dim LEDs in low light situations.

As such I have nothing against adding support for HSL or other color 
space based brightness calculations. It might just need to be 
configurable what kind of mode is being used based on hardware solution 
in place. HSL seem to need a bit of fixed point math. Got floating point 
version working already but that does not work with kernel space so one 
needs to adapt it to fixed point.

One problem here is to figure out is if user configures some color -- is 
it configured with 100% brightness eg. Should one calculate RGB->HSL and 
then scale L with brightness and calculate RGB back for setting color -- 
or does it mean replacing L with brightness value?

Additional problem is then if you have let's say yellow LED color 
element there. How would one scale that then? Linear is of course easy. 
If you need to configure this to some color space then how does one 
define the color in device tree so that such color space conversion is 
possible? One possible solution is to calibrate the curve (like what you 
do with LCD calibration) and then just assume brightness as linear 
brightness value in that case.

Or if you have multi-color LED with red and green but no other color 
elements. How does brightness scaling work with this one?

>>> I have another proposal, being a mix of what has been discussed so far:
>>>
>>>     RGB LED class will expose following files:
>>>     a) available by default:
>>>       - red, green, blue
>>>         Writing any of these file will result in writing corresponding
>>>         device register.
>>
>> Problem with this is that we are basically back at square one and one cannot
>> do "atomic" color change with this.
>>
>> In order to set or activate new values one would need "load values" file or
>> such that when writing to it would activate new values. However it becomes
>> quite clumsy interface at that point as you need to handle multiple writes
>> to multiple files and makes those operations rather slow.
> 
> If you don't like the interface, create an shared library. It may be
> neccessary, anyway, for the color operations.
> 
> You say it is "rather slow" to change all 3 colors. How long does it
> take, and how long do you need it to take?

Some times in embedded linux systems you can see "stalls" in operation 
of an application flow eg. time is spent in different places. I believe 
"slowest" CPU with embedded linux we are using is Atmel's AT91 series 
(ARM9) and executing code in there can at times be a bit time consuming.

I have seen delays like 18ms in TI's AM335x CPU series (Cortex-A8) and 
not even too high load situations (eg. breaking some serial protocols 
because of breaks in transmission in-between transfer without being a 
problem in application code as such). It is completely different story 
when there is a bit of load in system or some special situation in the 
kernel/OS.

Running high priority thread for configuring LEDs to avoid problems 
sounds like a wrong solution.

Co-worker of mine tried multi-color LED brightness sliding from user 
space with current PWM led driver and it was visible from eye that it 
was not timed smoothly.

For GPIO LED we decided to use out-of-tree solution for multi-color LEDs 
because we didn't want to see wrong colors in LEDs or sliding colors. 
For this we have color preset table in device tree and with it color 
change is more or less atomic. And also it supports kernel based LED 
blinking with whatever color you have configured there first.

For PWM controlled multi-color LEDs we don't yet have a solution. We 
need configurable color kernel based blinking.

With Jacek's proposed interface one could do kernel based blinking if 
brightness is simulated or calculated (if trigger's ON brightness can be 
configured). Only problem I suppose is color transition from A to B 
state and after that the blinking would work nicely as target color 
would already be known by driver.

If we could figure out acceptable solution for color transition problem 
then I suppose all parties would be happy?

Thanks,
Vesa Jääskeläinen

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-04 19:12                       ` Jacek Anaszewski
@ 2019-01-04 20:12                         ` Pavel Machek
  2019-01-04 21:37                           ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2019-01-04 20:12 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

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

Hi!

> >I suppose if one would just make it an array of values (separated by
> >space) and then one file with string array of color element names and on
> >file with maximum value array it could be within those words.
> >
> >The it would be something like:
> >
> >$ echo "23 54 32" > color
> 
> Go ahead, but first convince Pavel, and then Greg :-)
> 
> I'd personally would not have much against, especially that the
> list of values will not grow for that one like in case of old patch set
> [0] where Pavel and Greg thwarted my similar attempt.

Oh, you can get this past Pavel (and probably Greg) -- if you have a
good reason. Performance is _not_ a good reason. You don't need to
change LED color 50000 times a second.

If you can demonstrate a reasonable design, where user selects color
from well-known RGB pallete and either kernel or library+kernel acts
to set that color on the LED, we can talk.

When user asks for white, it has to be white. Exact color temperature
does not matter. When user asks for pink, it has to be pink. Again,
exact color does not matter; different monitors display slightly
different colors, too.

									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-04 19:49                         ` Vesa Jääskeläinen
@ 2019-01-04 20:43                           ` Pavel Machek
  0 siblings, 0 replies; 106+ messages in thread
From: Pavel Machek @ 2019-01-04 20:43 UTC (permalink / raw)
  To: Vesa Jääskeläinen
  Cc: Jacek Anaszewski, Dan Murphy, robh+dt, devicetree, linux-kernel,
	linux-leds

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

Hi!

> >And... LEDs are linear-enough as it is. That is not a problem. But RGB
> >does _not_ expect linear response. That's why colors are _way_ off currently.
> 
> Example what I was given was some LEDs are off for let's say 20% of PWM
> linearity and then there is non-linear curve for PWM value vs. intensity
> (this was in context of white LCD backlight).

Well, we'll do non-linear curve calibration if we have to. 

> As such I have nothing against adding support for HSL or other color space
> based brightness calculations. It might just need to be configurable what
> kind of mode is being used based on hardware solution in place. HSL seem to
> need a bit of fixed point math. Got floating point version working already
> but that does not work with kernel space so one needs to adapt it to fixed
> point.

First, we need _some_ kind of solution. Then we can decide kernel
vs. library. We can do floats in kernel too, if really required.

> One problem here is to figure out is if user configures some color -- is it
> configured with 100% brightness eg. Should one calculate RGB->HSL and then
> scale L with brightness and calculate RGB back for setting color -- or does
> it mean replacing L with brightness value?

I don't understand the question here.

> Additional problem is then if you have let's say yellow LED color element
> there. How would one scale that then? Linear is of course easy. If you need
> to configure this to some color space then how does one define the color in
> device tree so that such color space conversion is possible? One possible
> solution is to calibrate the curve (like what you do with LCD calibration)
> and then just assume brightness as linear brightness value in that
> case.

Calibrated curves would be nice...

For leds, you should be able to list the wavelength, right?

> Or if you have multi-color LED with red and green but no other color
> elements. How does brightness scaling work with this one?

I'd ignore that for now.

> >You say it is "rather slow" to change all 3 colors. How long does it
> >take, and how long do you need it to take?
> 
> Some times in embedded linux systems you can see "stalls" in operation of an
> application flow eg. time is spent in different places. I believe "slowest"
> CPU with embedded linux we are using is Atmel's AT91 series (ARM9) and
> executing code in there can at times be a bit time consuming.
> 
> I have seen delays like 18ms in TI's AM335x CPU series (Cortex-A8) and not
> even too high load situations (eg. breaking some serial protocols because of
> breaks in transmission in-between transfer without being a problem in
> application code as such). It is completely different story when there is a
> bit of load in system or some special situation in the kernel/OS.
> 
> Running high priority thread for configuring LEDs to avoid problems sounds
> like a wrong solution.
> 
> Co-worker of mine tried multi-color LED brightness sliding from user space
> with current PWM led driver and it was visible from eye that it was not
> timed smoothly.

Ok, 18msec is _way_ higher than sysfs overhead (like 400x?). If you
have slow i2c or something, then you'll get fun stuff, no matter what
the kernel<->user interface.

> For PWM controlled multi-color LEDs we don't yet have a solution. We need
> configurable color kernel based blinking.

> If we could figure out acceptable solution for color transition problem then
> I suppose all parties would be happy?

If you can get LEDs to display the colors in similar way monitors do,
that will be major step forward. Then we can design the rest, or maybe
ressurect the HSV patch.

									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-04 20:12                         ` Pavel Machek
@ 2019-01-04 21:37                           ` Jacek Anaszewski
  2019-01-04 22:07                             ` Pavel Machek
  2019-01-05  0:39                             ` Vesa Jääskeläinen
  0 siblings, 2 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-04 21:37 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

On 1/4/19 9:12 PM, Pavel Machek wrote:
> Hi!
> 
>>> I suppose if one would just make it an array of values (separated by
>>> space) and then one file with string array of color element names and on
>>> file with maximum value array it could be within those words.
>>>
>>> The it would be something like:
>>>
>>> $ echo "23 54 32" > color
>>
>> Go ahead, but first convince Pavel, and then Greg :-)
>>
>> I'd personally would not have much against, especially that the
>> list of values will not grow for that one like in case of old patch set
>> [0] where Pavel and Greg thwarted my similar attempt.
> 
> Oh, you can get this past Pavel (and probably Greg) -- if you have a
> good reason. Performance is _not_ a good reason. You don't need to
> change LED color 50000 times a second.

We would need to do some profiling here to check if the problem exists.

But, aside from that hypothetic issue, we need a solution for
LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
via a single register write. How would you propose to address that?

> If you can demonstrate a reasonable design, where user selects color
> from well-known RGB pallete and either kernel or library+kernel acts
> to set that color on the LED, we can talk.
> 
> When user asks for white, it has to be white. Exact color temperature
> does not matter. When user asks for pink, it has to be pink. Again,
> exact color does not matter; different monitors display slightly
> different colors, too
-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-04 21:37                           ` Jacek Anaszewski
@ 2019-01-04 22:07                             ` Pavel Machek
  2019-01-05 12:16                               ` Jacek Anaszewski
  2019-01-05  0:39                             ` Vesa Jääskeläinen
  1 sibling, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2019-01-04 22:07 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

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

Hi!

> But, aside from that hypothetic issue, we need a solution for
> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
> via a single register write. How would you propose to address that?

So they have hardware feature that allows control of 3 LEDs at the
same time, right?

Actually turris routers (IIRC) have similar feature, but shared for
all their LEDs.

I'd suggest simply ignoring that feature for now :-).

We will need to solve RGB leds somehow, hopefully this is solved with
it.

Best regards,
									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-04 21:37                           ` Jacek Anaszewski
  2019-01-04 22:07                             ` Pavel Machek
@ 2019-01-05  0:39                             ` Vesa Jääskeläinen
  2019-01-07 19:34                               ` Dan Murphy
  2019-01-07 21:13                               ` Jacek Anaszewski
  1 sibling, 2 replies; 106+ messages in thread
From: Vesa Jääskeläinen @ 2019-01-05  0:39 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

Hi Jacek,

On 04/01/2019 23.37, Jacek Anaszewski wrote:
> But, aside from that hypothetic issue, we need a solution for
> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
> via a single register write. How would you propose to address that?

You could model it to something like this in device tree:

led-module @ <i2c-address> {
	compatible = "lp5024";

	// There is in hardware setup to use either linear or
	// logarithmic scaling:
	//enable-logarithmic-brightness;

	led0 {
		// this will create led instance for LED0 in lp5024
		label = "lp-led0";
		
		// This specifies LED number within lp5024
		led-index = <0>;   // set output-base as 0*3 == 0
		
		element-red {
			// refers to OUT0
			output-offset = <0>;
		};
		
		element-green {
			// refers to OUT1
			output-offset = <1>;
		};
		
		element-blue {
			// refers to OUT2
			output-offset = <2>;
		};
		
	};	

	led1 {
		// this will create led instance for LED1 in lp5024
		label = "lp-led1";
		
		// This specifies LED number within lp5024
		led-index = <1>;   // set output-base as 1*3 == 3

		element-red {
			// refers to OUT3
			output-offset = <0>;
		};
		
		element-green {
			// refers to OUT4
			output-offset = <1>;
		};
		
		element-blue {
			// refers to OUT5
			output-offset = <2>;
		};
		
	};

	bank-led {
		// this will create led instance for bank leds in lp5024
		label = "lp-bank-led";

		// configured bank led configuration
		led-index = <2 3 4 5 6 7>;
		// As here is list of led-indices this entry is
		// assumed to be bank configuration. Bank mode is enable
		// for the indices.

		// set output-base as BANK A

		element-red {
			// refers to BANK A
			output-offset = <0>;
		};
		
		element-green {
			// refers to BANK B
			output-offset = <1>;
		};
		
		element-blue {
			// refers to BANK C
			output-offset = <2>;
		};
	};	
};

This would then create three led instances and each led instance has 
brightness setting and that goes straight to hardware.

If one would want to override hardware control for brightness then I 
suppose you would define in led node something like:

	brightness-model = "hsl"

This would then pick red, green and blue elements for hsl calculations 
and others color elements for linear. LED specific hardware brightness 
would then be either 0 or 0xFF depending if all of LED color elements 
are zero or not.

Would that kind of model work?

Thanks,
Vesa Jääskeläinen

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-04 22:07                             ` Pavel Machek
@ 2019-01-05 12:16                               ` Jacek Anaszewski
  2019-01-05 12:31                                 ` Pavel Machek
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-05 12:16 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

Hi Pavel,

On 1/4/19 11:07 PM, Pavel Machek wrote:
> Hi!
> 
>> But, aside from that hypothetic issue, we need a solution for
>> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
>> via a single register write. How would you propose to address that?
> 
> So they have hardware feature that allows control of 3 LEDs at the
> same time, right?
> 
> Actually turris routers (IIRC) have similar feature, but shared for
> all their LEDs.
> 
> I'd suggest simply ignoring that feature for now :-).

Why not use brightness file for that?

> We will need to solve RGB leds somehow, hopefully this is solved with
> it.

When? With this attitude we will procrastinate it forever.
It's been almost 3 years since first HSV patches.

I proposed rough design of LED RGB class interface in [0].
If you find it totally flawed, then please spot the problems.
If not, let's improve it and implement.

[0] https://lkml.org/lkml/2019/1/3/550

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-05 12:16                               ` Jacek Anaszewski
@ 2019-01-05 12:31                                 ` Pavel Machek
  2019-01-05 13:16                                   ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2019-01-05 12:31 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

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

> >We will need to solve RGB leds somehow, hopefully this is solved with
> >it.
> 
> When? With this attitude we will procrastinate it forever.
> It's been almost 3 years since first HSV patches.
> 
> I proposed rough design of LED RGB class interface in [0].
> If you find it totally flawed, then please spot the problems.
> If not, let's improve it and implement.

That is fatally flawed, and inferior to the HSV patches, sorry...

Grab yourself an RGB LED and play with it; you'll see what the
problems are. It is hard to explain colors over email...

									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-05 12:31                                 ` Pavel Machek
@ 2019-01-05 13:16                                   ` Jacek Anaszewski
  2019-01-05 22:12                                     ` Generic RGB LED support was " Pavel Machek
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-05 13:16 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

On 1/5/19 1:31 PM, Pavel Machek wrote:
>>> We will need to solve RGB leds somehow, hopefully this is solved with
>>> it.
>>
>> When? With this attitude we will procrastinate it forever.
>> It's been almost 3 years since first HSV patches.
>>
>> I proposed rough design of LED RGB class interface in [0].
>> If you find it totally flawed, then please spot the problems.
>> If not, let's improve it and implement.
> 
> That is fatally flawed, and inferior to the HSV patches, sorry...

Please spot the problems.

> Grab yourself an RGB LED and play with it; you'll see what the
> problems are. It is hard to explain colors over email...

Video [0] gives some overview of lp5024 capabilities.

I don't see any problems in exposing separate red,green,blue
files and brightness for the devices with hardware support for
that.

I want to push things forward and I'm going to ask Dan
to give this design a try.

[0] https://www.youtube.com/watch?v=qdt-alh8i6E

-- 
Best regards,
Jacek Anaszewski

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

* Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-05 13:16                                   ` Jacek Anaszewski
@ 2019-01-05 22:12                                     ` " Pavel Machek
  2019-01-06 15:52                                       ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2019-01-05 22:12 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

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

Hi!

> >Grab yourself an RGB LED and play with it; you'll see what the
> >problems are. It is hard to explain colors over email...
> 
> Video [0] gives some overview of lp5024 capabilities.
> 
> I don't see any problems in exposing separate red,green,blue
> files and brightness for the devices with hardware support for
> that.

Well, that's what we do today, as three separate LEDs, right?

I don't have problem with that, either; other drivers already do
that. He's free to use existing same interface.

But that is insufficient, as it does not allow simple stuff, such as
turning led "white".

So... perhaps we should agree on requirements, first, and then we can
discuss solutions?

Requirements for RGB LED interface:

1) Userspace should be able to set the white color

2) Userspace should be able to arbitrary color from well known list
and it should approximately match what would CRT, LCD or OLED monitor display

    2a) LEDs probably slightly change color as they age. That's out of
    scope, unless the variation is much greater than on monitors.

    2b) Manufacturing differences cause small color variation. Again,
    that's out of scope, unless the variation is much greater than on
    monitors.

Nice to have features:

3) Full range of available colors/intensities should be available to
userspace

4) Interface should work well with existing triggers

5) It would be nice if userland knew how many lumens are produced at
each wavelength for each setting (again, minus aging and manufacturing
variations).

6) Complexity of math in kernel should be low, and preferably it
should be integer or fixed point

Problems:

a) RGB LEDs are usually not balanced. Setting 100% PWM on
red/green/blue channels will result in nothing close to white
light. In fact, to get white light on N900, blue and green channel's
PWM needs to be set pretty low, as in 5%.

b) LED class does not define any relation between "brightness" in
sysfs and ammount of light in lumens. Some drivers use close to linear
relation, some use exponential relation. Human eyes percieve logarithm
of lumens. RGB color model uses even more complex function.

c) Except for white LEDs, LEDs are basically sources of single
wavelength of light, while CRTs and LCDs produce broader
spectrums.

d) RG, RGBW and probably other LED combinations exist.

e) Not all "red" LEDs will produce same wavelength. Similar
differences will exist for other colors.

f) We have existing RGB LEDs represented as three separate
monochromatic LEDs in sysfs.


-- 
(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] 106+ messages in thread

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-05 22:12                                     ` Generic RGB LED support was " Pavel Machek
@ 2019-01-06 15:52                                       ` Jacek Anaszewski
  2019-01-07 19:13                                         ` Jacek Anaszewski
  2019-01-08 22:59                                         ` Pavel Machek
  0 siblings, 2 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-06 15:52 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

Hi Pavel,

On 1/5/19 11:12 PM, Pavel Machek wrote:
> Hi!
> 
>>> Grab yourself an RGB LED and play with it; you'll see what the
>>> problems are. It is hard to explain colors over email...
>>
>> Video [0] gives some overview of lp5024 capabilities.
>>
>> I don't see any problems in exposing separate red,green,blue
>> files and brightness for the devices with hardware support for
>> that.
> 
> Well, that's what we do today, as three separate LEDs, right?

No. It doesn't allow for setting color intensity by having
the color fixed beforehand. Below is relevant excerpt from
the lp5024 documentation. This is not something that can be
mapped to RGB color space, but rather to HSV/HSL, with the
reservation that the hardware implementation uses PWM
for setting color intensity.

<quote>
8.3.1.2 Independent Intensity Control Per RGB LED Module

When color is fixed, the independent intensity-control is used to
achieve accurate and flexible dimming control for every RGB LED module.

8.3.1.2.1 Intensity-Control Register Configuration

Every three consecutive output channels are assigned to their respective
intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
device allows 256-step intensity control for each RGB LED module, which
helps achieve a smooth dimming effect.
</quote>

> I don't have problem with that, either; other drivers already do
> that. He's free to use existing same interface.
> 
> But that is insufficient, as it does not allow simple stuff, such as
> turning led "white".
> 
> So... perhaps we should agree on requirements, first, and then we can
> discuss solutions?
> 
> Requirements for RGB LED interface:
> 
> 1) Userspace should be able to set the white color
> 
> 2) Userspace should be able to arbitrary color from well known list
> and it should approximately match what would CRT, LCD or OLED monitor display

The difference is that monitor display driver is pre-calibrated
for given display by the manufacturer. With the LED controllers the
manufacturer has no control over what LEDs will be connected to the
iouts. Therefore it should be not surprising that colors produced
by custom LEDs are not as user would expect when comparing to
the RGB color displayed on the monitor display.

TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
that show how to produce various patterns with use of the reference
board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].

Document [0] mentions also specific "Design considerations" in the
chapter 2.2:

<quote>
Several considerations are taken into account for this particular design:
• LED map (ring) for meeting the requirement of popular human-machine 
interaction style.
• LED size, numbers and the diffuse design for meeting lighting pattern 
uniformity.
• Analog dimming in the difference ambient light lux without losing 
dimming resolution in lighting pattern.

These considerations apply to most human-machine interaction end 
equipment with day and night vision
designs in some way, but the designer must decide the particular 
considerations to take into account for a
specific design.
</quote>

This renders your requirement 2) infeasible with use of custom LEDs
any fixed algorithm, since the final effect will always heavily depend
on the LED circuit design.

> 
>      2a) LEDs probably slightly change color as they age. That's out of
>      scope, unless the variation is much greater than on monitors.
> 
>      2b) Manufacturing differences cause small color variation. Again,
>      that's out of scope, unless the variation is much greater than on
>      monitors.
> 
> Nice to have features:
> 
> 3) Full range of available colors/intensities should be available to
> userspace
> 
> 4) Interface should work well with existing triggers
> 
> 5) It would be nice if userland knew how many lumens are produced at
> each wavelength for each setting (again, minus aging and manufacturing
> variations).
> 
> 6) Complexity of math in kernel should be low, and preferably it
> should be integer or fixed point
> 
> Problems:
> 
> a) RGB LEDs are usually not balanced. Setting 100% PWM on
> red/green/blue channels will result in nothing close to white
> light. In fact, to get white light on N900, blue and green channel's
> PWM needs to be set pretty low, as in 5%.
> 
> b) LED class does not define any relation between "brightness" in
> sysfs and ammount of light in lumens. Some drivers use close to linear
> relation, some use exponential relation. Human eyes percieve logarithm
> of lumens. RGB color model uses even more complex function.
> 
> c) Except for white LEDs, LEDs are basically sources of single
> wavelength of light, while CRTs and LCDs produce broader
> spectrums.
> 
> d) RG, RGBW and probably other LED combinations exist.
> 
> e) Not all "red" LEDs will produce same wavelength. Similar
> differences will exist for other colors.
> 
> f) We have existing RGB LEDs represented as three separate
> monochromatic LEDs in sysfs.

One general question: do you have any solutions in store?

[0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
[1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf

-- 
Best regards,
Jacek Anaszewski

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-06 15:52                                       ` Jacek Anaszewski
@ 2019-01-07 19:13                                         ` Jacek Anaszewski
  2019-01-07 19:36                                           ` Dan Murphy
  2019-01-08 22:59                                         ` Pavel Machek
  1 sibling, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-07 19:13 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
> Hi Pavel,
> 
> On 1/5/19 11:12 PM, Pavel Machek wrote:
>> Hi!
>>
>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>> problems are. It is hard to explain colors over email...
>>>
>>> Video [0] gives some overview of lp5024 capabilities.
>>>
>>> I don't see any problems in exposing separate red,green,blue
>>> files and brightness for the devices with hardware support for
>>> that.
>>
>> Well, that's what we do today, as three separate LEDs, right?
> 
> No. It doesn't allow for setting color intensity by having
> the color fixed beforehand. Below is relevant excerpt from
> the lp5024 documentation. This is not something that can be
> mapped to RGB color space, but rather to HSV/HSL, with the
> reservation that the hardware implementation uses PWM
> for setting color intensity.
> 
> <quote>
> 8.3.1.2 Independent Intensity Control Per RGB LED Module
> 
> When color is fixed, the independent intensity-control is used to
> achieve accurate and flexible dimming control for every RGB LED module.
> 
> 8.3.1.2.1 Intensity-Control Register Configuration
> 
> Every three consecutive output channels are assigned to their respective
> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
> device allows 256-step intensity control for each RGB LED module, which
> helps achieve a smooth dimming effect.
> </quote>
> 
>> I don't have problem with that, either; other drivers already do
>> that. He's free to use existing same interface.
>>
>> But that is insufficient, as it does not allow simple stuff, such as
>> turning led "white".
>>
>> So... perhaps we should agree on requirements, first, and then we can
>> discuss solutions?
>>
>> Requirements for RGB LED interface:
>>
>> 1) Userspace should be able to set the white color
>>
>> 2) Userspace should be able to arbitrary color from well known list
>> and it should approximately match what would CRT, LCD or OLED monitor 
>> display
> 
> The difference is that monitor display driver is pre-calibrated
> for given display by the manufacturer. With the LED controllers the
> manufacturer has no control over what LEDs will be connected to the
> iouts. Therefore it should be not surprising that colors produced
> by custom LEDs are not as user would expect when comparing to
> the RGB color displayed on the monitor display.
> 
> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
> that show how to produce various patterns with use of the reference
> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
> 
> Document [0] mentions also specific "Design considerations" in the
> chapter 2.2:
> 
> <quote>
> Several considerations are taken into account for this particular design:
> • LED map (ring) for meeting the requirement of popular human-machine 
> interaction style.
> • LED size, numbers and the diffuse design for meeting lighting pattern 
> uniformity.
> • Analog dimming in the difference ambient light lux without losing 
> dimming resolution in lighting pattern.
> 
> These considerations apply to most human-machine interaction end 
> equipment with day and night vision
> designs in some way, but the designer must decide the particular 
> considerations to take into account for a
> specific design.
> </quote>
> 
> This renders your requirement 2) infeasible with use of custom LEDs
> any fixed algorithm, since the final effect will always heavily depend

Typo here: s/any fixed/and fixed/

> on the LED circuit design.
> 
>>
>>      2a) LEDs probably slightly change color as they age. That's out of
>>      scope, unless the variation is much greater than on monitors.
>>
>>      2b) Manufacturing differences cause small color variation. Again,
>>      that's out of scope, unless the variation is much greater than on
>>      monitors.
>>
>> Nice to have features:
>>
>> 3) Full range of available colors/intensities should be available to
>> userspace
>>
>> 4) Interface should work well with existing triggers
>>
>> 5) It would be nice if userland knew how many lumens are produced at
>> each wavelength for each setting (again, minus aging and manufacturing
>> variations).
>>
>> 6) Complexity of math in kernel should be low, and preferably it
>> should be integer or fixed point
>>
>> Problems:
>>
>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>> red/green/blue channels will result in nothing close to white
>> light. In fact, to get white light on N900, blue and green channel's
>> PWM needs to be set pretty low, as in 5%.
>>
>> b) LED class does not define any relation between "brightness" in
>> sysfs and ammount of light in lumens. Some drivers use close to linear
>> relation, some use exponential relation. Human eyes percieve logarithm
>> of lumens. RGB color model uses even more complex function.
>>
>> c) Except for white LEDs, LEDs are basically sources of single
>> wavelength of light, while CRTs and LCDs produce broader
>> spectrums.
>>
>> d) RG, RGBW and probably other LED combinations exist.
>>
>> e) Not all "red" LEDs will produce same wavelength. Similar
>> differences will exist for other colors.
>>
>> f) We have existing RGB LEDs represented as three separate
>> monochromatic LEDs in sysfs.
> 
> One general question: do you have any solutions in store?
> 
> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-05  0:39                             ` Vesa Jääskeläinen
@ 2019-01-07 19:34                               ` Dan Murphy
  2019-01-09  6:20                                 ` Vesa Jääskeläinen
  2019-01-07 21:13                               ` Jacek Anaszewski
  1 sibling, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-07 19:34 UTC (permalink / raw)
  To: Vesa Jääskeläinen, Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Vesa

On 1/4/19 6:39 PM, Vesa Jääskeläinen wrote:
> Hi Jacek,
> 
> On 04/01/2019 23.37, Jacek Anaszewski wrote:
>> But, aside from that hypothetic issue, we need a solution for
>> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
>> via a single register write. How would you propose to address that?
> 
> You could model it to something like this in device tree:
> 
> led-module @ <i2c-address> {
>     compatible = "lp5024";
> 
>     // There is in hardware setup to use either linear or
>     // logarithmic scaling:
>     //enable-logarithmic-brightness;
> 
>     led0 {
>         // this will create led instance for LED0 in lp5024
>         label = "lp-led0";
>        
>         // This specifies LED number within lp5024
>         led-index = <0>;   // set output-base as 0*3 == 0
>        
>         element-red {
>             // refers to OUT0
>             output-offset = <0>;
>         };
>        
>         element-green {
>             // refers to OUT1
>             output-offset = <1>;
>         };
>        
>         element-blue {
>             // refers to OUT2
>             output-offset = <2>;
>         };
>        
>     };   
> 
>     led1 {
>         // this will create led instance for LED1 in lp5024
>         label = "lp-led1";
>        
>         // This specifies LED number within lp5024
>         led-index = <1>;   // set output-base as 1*3 == 3
> 

Can we not use led-sources like I have done already?
I really like to keep the DT nodes simple and re-use nodes that exist if possible.

My code already maps and groups the outputs into the associated banks

Dan
<snip>

-- 
------------------
Dan Murphy

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-07 19:13                                         ` Jacek Anaszewski
@ 2019-01-07 19:36                                           ` Dan Murphy
  2019-01-07 20:59                                             ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-07 19:36 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

Jacek

On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>> Hi Pavel,
>>
>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>> Hi!
>>>
>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>> problems are. It is hard to explain colors over email...
>>>>
>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>
>>>> I don't see any problems in exposing separate red,green,blue
>>>> files and brightness for the devices with hardware support for
>>>> that.
>>>
>>> Well, that's what we do today, as three separate LEDs, right?
>>
>> No. It doesn't allow for setting color intensity by having
>> the color fixed beforehand. Below is relevant excerpt from
>> the lp5024 documentation. This is not something that can be
>> mapped to RGB color space, but rather to HSV/HSL, with the
>> reservation that the hardware implementation uses PWM
>> for setting color intensity.
>>
>> <quote>
>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>
>> When color is fixed, the independent intensity-control is used to
>> achieve accurate and flexible dimming control for every RGB LED module.
>>
>> 8.3.1.2.1 Intensity-Control Register Configuration
>>
>> Every three consecutive output channels are assigned to their respective
>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>> device allows 256-step intensity control for each RGB LED module, which
>> helps achieve a smooth dimming effect.
>> </quote>
>>
>>> I don't have problem with that, either; other drivers already do
>>> that. He's free to use existing same interface.
>>>
>>> But that is insufficient, as it does not allow simple stuff, such as
>>> turning led "white".
>>>
>>> So... perhaps we should agree on requirements, first, and then we can
>>> discuss solutions?
>>>
>>> Requirements for RGB LED interface:
>>>
>>> 1) Userspace should be able to set the white color
>>>
>>> 2) Userspace should be able to arbitrary color from well known list
>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>
>> The difference is that monitor display driver is pre-calibrated
>> for given display by the manufacturer. With the LED controllers the
>> manufacturer has no control over what LEDs will be connected to the
>> iouts. Therefore it should be not surprising that colors produced
>> by custom LEDs are not as user would expect when comparing to
>> the RGB color displayed on the monitor display.
>>
>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>> that show how to produce various patterns with use of the reference
>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>
>> Document [0] mentions also specific "Design considerations" in the
>> chapter 2.2:
>>
>> <quote>
>> Several considerations are taken into account for this particular design:
>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>
>> These considerations apply to most human-machine interaction end equipment with day and night vision
>> designs in some way, but the designer must decide the particular considerations to take into account for a
>> specific design.
>> </quote>
>>
>> This renders your requirement 2) infeasible with use of custom LEDs
>> any fixed algorithm, since the final effect will always heavily depend
> 
> Typo here: s/any fixed/and fixed/
> 
>> on the LED circuit design.
>>
>>>
>>>      2a) LEDs probably slightly change color as they age. That's out of
>>>      scope, unless the variation is much greater than on monitors.
>>>
>>>      2b) Manufacturing differences cause small color variation. Again,
>>>      that's out of scope, unless the variation is much greater than on
>>>      monitors.
>>>
>>> Nice to have features:
>>>
>>> 3) Full range of available colors/intensities should be available to
>>> userspace
>>>
>>> 4) Interface should work well with existing triggers
>>>
>>> 5) It would be nice if userland knew how many lumens are produced at
>>> each wavelength for each setting (again, minus aging and manufacturing
>>> variations).
>>>
>>> 6) Complexity of math in kernel should be low, and preferably it
>>> should be integer or fixed point
>>>
>>> Problems:
>>>
>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>> red/green/blue channels will result in nothing close to white
>>> light. In fact, to get white light on N900, blue and green channel's
>>> PWM needs to be set pretty low, as in 5%.
>>>
>>> b) LED class does not define any relation between "brightness" in
>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>> relation, some use exponential relation. Human eyes percieve logarithm
>>> of lumens. RGB color model uses even more complex function.
>>>
>>> c) Except for white LEDs, LEDs are basically sources of single
>>> wavelength of light, while CRTs and LCDs produce broader
>>> spectrums.
>>>
>>> d) RG, RGBW and probably other LED combinations exist.
>>>
>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>> differences will exist for other colors.
>>>
>>> f) We have existing RGB LEDs represented as three separate
>>> monochromatic LEDs in sysfs.
>>
>> One general question: do you have any solutions in store?
>>
>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>
> 

I just wanted to point out that there are 4 total devices right now that use the same mapping

LP5018, LP5024, LP5030 and the LP5036.

I can implement what ever we would like to I just need to know what to design against.

But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.

Dan

-- 
------------------
Dan Murphy

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-07 19:36                                           ` Dan Murphy
@ 2019-01-07 20:59                                             ` Jacek Anaszewski
  2019-01-07 21:14                                               ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-07 20:59 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

Dan,

On 1/7/19 8:36 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>> Hi Pavel,
>>>
>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>> Hi!
>>>>
>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>> problems are. It is hard to explain colors over email...
>>>>>
>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>
>>>>> I don't see any problems in exposing separate red,green,blue
>>>>> files and brightness for the devices with hardware support for
>>>>> that.
>>>>
>>>> Well, that's what we do today, as three separate LEDs, right?
>>>
>>> No. It doesn't allow for setting color intensity by having
>>> the color fixed beforehand. Below is relevant excerpt from
>>> the lp5024 documentation. This is not something that can be
>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>> reservation that the hardware implementation uses PWM
>>> for setting color intensity.
>>>
>>> <quote>
>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>
>>> When color is fixed, the independent intensity-control is used to
>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>
>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>
>>> Every three consecutive output channels are assigned to their respective
>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>> device allows 256-step intensity control for each RGB LED module, which
>>> helps achieve a smooth dimming effect.
>>> </quote>
>>>
>>>> I don't have problem with that, either; other drivers already do
>>>> that. He's free to use existing same interface.
>>>>
>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>> turning led "white".
>>>>
>>>> So... perhaps we should agree on requirements, first, and then we can
>>>> discuss solutions?
>>>>
>>>> Requirements for RGB LED interface:
>>>>
>>>> 1) Userspace should be able to set the white color
>>>>
>>>> 2) Userspace should be able to arbitrary color from well known list
>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>
>>> The difference is that monitor display driver is pre-calibrated
>>> for given display by the manufacturer. With the LED controllers the
>>> manufacturer has no control over what LEDs will be connected to the
>>> iouts. Therefore it should be not surprising that colors produced
>>> by custom LEDs are not as user would expect when comparing to
>>> the RGB color displayed on the monitor display.
>>>
>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>> that show how to produce various patterns with use of the reference
>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>
>>> Document [0] mentions also specific "Design considerations" in the
>>> chapter 2.2:
>>>
>>> <quote>
>>> Several considerations are taken into account for this particular design:
>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>
>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>> specific design.
>>> </quote>
>>>
>>> This renders your requirement 2) infeasible with use of custom LEDs
>>> any fixed algorithm, since the final effect will always heavily depend
>>
>> Typo here: s/any fixed/and fixed/
>>
>>> on the LED circuit design.
>>>
>>>>
>>>>       2a) LEDs probably slightly change color as they age. That's out of
>>>>       scope, unless the variation is much greater than on monitors.
>>>>
>>>>       2b) Manufacturing differences cause small color variation. Again,
>>>>       that's out of scope, unless the variation is much greater than on
>>>>       monitors.
>>>>
>>>> Nice to have features:
>>>>
>>>> 3) Full range of available colors/intensities should be available to
>>>> userspace
>>>>
>>>> 4) Interface should work well with existing triggers
>>>>
>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>> variations).
>>>>
>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>> should be integer or fixed point
>>>>
>>>> Problems:
>>>>
>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>> red/green/blue channels will result in nothing close to white
>>>> light. In fact, to get white light on N900, blue and green channel's
>>>> PWM needs to be set pretty low, as in 5%.
>>>>
>>>> b) LED class does not define any relation between "brightness" in
>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>> of lumens. RGB color model uses even more complex function.
>>>>
>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>> wavelength of light, while CRTs and LCDs produce broader
>>>> spectrums.
>>>>
>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>
>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>> differences will exist for other colors.
>>>>
>>>> f) We have existing RGB LEDs represented as three separate
>>>> monochromatic LEDs in sysfs.
>>>
>>> One general question: do you have any solutions in store?
>>>
>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>
>>
> 
> I just wanted to point out that there are 4 total devices right now that use the same mapping
> 
> LP5018, LP5024, LP5030 and the LP5036.
> 
> I can implement what ever we would like to I just need to know what to design against.

As you can see from the discussion in this thread it may take some
time to work out the interface satisfying everyone. I made some design
proposal, but Pavel had no warm word for it. It would be easier if
we had more opinions.

How do you feel about using brightness file for setting LEDn_BRIGHTNESS?

Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
increasing color lightness (i.e. the pattern presented in the video [0]
starting from 1:22)?

> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.

Do what you deem most suitable for you. We are here only to help
merging the patches, but keeping in mind that kernel interface once
introduced must be preserved forever. Therefore we need to do our
best to make the best possible design decisions.

[0] https://www.youtube.com/watch?v=qdt-alh8i6E

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-05  0:39                             ` Vesa Jääskeläinen
  2019-01-07 19:34                               ` Dan Murphy
@ 2019-01-07 21:13                               ` Jacek Anaszewski
  2019-01-07 21:15                                 ` Dan Murphy
  2019-01-09  6:46                                 ` Vesa Jääskeläinen
  1 sibling, 2 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-07 21:13 UTC (permalink / raw)
  To: Vesa Jääskeläinen, Pavel Machek
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

Hi Vesa,

On 1/5/19 1:39 AM, Vesa Jääskeläinen wrote:
> Hi Jacek,
> 
> On 04/01/2019 23.37, Jacek Anaszewski wrote:
>> But, aside from that hypothetic issue, we need a solution for
>> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
>> via a single register write. How would you propose to address that?
> 
> You could model it to something like this in device tree:
> 
> led-module @ <i2c-address> {
>      compatible = "lp5024";
> 
>      // There is in hardware setup to use either linear or
>      // logarithmic scaling:
>      //enable-logarithmic-brightness;
> 
>      led0 {
>          // this will create led instance for LED0 in lp5024
>          label = "lp-led0";
> 
>          // This specifies LED number within lp5024
>          led-index = <0>;   // set output-base as 0*3 == 0
> 
>          element-red {
>              // refers to OUT0
>              output-offset = <0>;
>          };
> 
>          element-green {
>              // refers to OUT1
>              output-offset = <1>;
>          };
> 
>          element-blue {
>              // refers to OUT2
>              output-offset = <2>;
>          };
> 
>      };
> 
>      led1 {
>          // this will create led instance for LED1 in lp5024
>          label = "lp-led1";
> 
>          // This specifies LED number within lp5024
>          led-index = <1>;   // set output-base as 1*3 == 3
> 
>          element-red {
>              // refers to OUT3
>              output-offset = <0>;
>          };
> 
>          element-green {
>              // refers to OUT4
>              output-offset = <1>;
>          };
> 
>          element-blue {
>              // refers to OUT5
>              output-offset = <2>;
>          };
> 
>      };
> 
>      bank-led {
>          // this will create led instance for bank leds in lp5024
>          label = "lp-bank-led";
> 
>          // configured bank led configuration
>          led-index = <2 3 4 5 6 7>;
>          // As here is list of led-indices this entry is
>          // assumed to be bank configuration. Bank mode is enable
>          // for the indices.
> 
>          // set output-base as BANK A
> 
>          element-red {
>              // refers to BANK A
>              output-offset = <0>;
>          };
> 
>          element-green {
>              // refers to BANK B
>              output-offset = <1>;
>          };
> 
>          element-blue {
>              // refers to BANK C
>              output-offset = <2>;
>          };
>      };
> };
> 
> This would then create three led instances and each led instance has 
> brightness setting and that goes straight to hardware.
> 
> If one would want to override hardware control for brightness then I 
> suppose you would define in led node something like:
> 
>      brightness-model = "hsl"
> 
> This would then pick red, green and blue elements for hsl calculations 
> and others color elements for linear. LED specific hardware brightness 
> would then be either 0 or 0xFF depending if all of LED color elements 
> are zero or not.
> 
> Would that kind of model work?

I'd prefer to have single RGB LED device. And your DT design
is unnecessarily complex and a bit confusing.

Also, you provided scarce information about sysfs interface.
It would be nice to see the sequence of commands.

-- 
Best regards,
Jacek Anaszewski

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-07 20:59                                             ` Jacek Anaszewski
@ 2019-01-07 21:14                                               ` Dan Murphy
  2019-01-08 21:18                                                 ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-07 21:14 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

Jacek

On 1/7/19 2:59 PM, Jacek Anaszewski wrote:
> Dan,
> 
> On 1/7/19 8:36 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>>> Hi Pavel,
>>>>
>>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>>> Hi!
>>>>>
>>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>>> problems are. It is hard to explain colors over email...
>>>>>>
>>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>>
>>>>>> I don't see any problems in exposing separate red,green,blue
>>>>>> files and brightness for the devices with hardware support for
>>>>>> that.
>>>>>
>>>>> Well, that's what we do today, as three separate LEDs, right?
>>>>
>>>> No. It doesn't allow for setting color intensity by having
>>>> the color fixed beforehand. Below is relevant excerpt from
>>>> the lp5024 documentation. This is not something that can be
>>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>>> reservation that the hardware implementation uses PWM
>>>> for setting color intensity.
>>>>
>>>> <quote>
>>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>>
>>>> When color is fixed, the independent intensity-control is used to
>>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>>
>>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>>
>>>> Every three consecutive output channels are assigned to their respective
>>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>>> device allows 256-step intensity control for each RGB LED module, which
>>>> helps achieve a smooth dimming effect.
>>>> </quote>
>>>>
>>>>> I don't have problem with that, either; other drivers already do
>>>>> that. He's free to use existing same interface.
>>>>>
>>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>>> turning led "white".
>>>>>
>>>>> So... perhaps we should agree on requirements, first, and then we can
>>>>> discuss solutions?
>>>>>
>>>>> Requirements for RGB LED interface:
>>>>>
>>>>> 1) Userspace should be able to set the white color
>>>>>
>>>>> 2) Userspace should be able to arbitrary color from well known list
>>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>>
>>>> The difference is that monitor display driver is pre-calibrated
>>>> for given display by the manufacturer. With the LED controllers the
>>>> manufacturer has no control over what LEDs will be connected to the
>>>> iouts. Therefore it should be not surprising that colors produced
>>>> by custom LEDs are not as user would expect when comparing to
>>>> the RGB color displayed on the monitor display.
>>>>
>>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>>> that show how to produce various patterns with use of the reference
>>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>>
>>>> Document [0] mentions also specific "Design considerations" in the
>>>> chapter 2.2:
>>>>
>>>> <quote>
>>>> Several considerations are taken into account for this particular design:
>>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>>
>>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>>> specific design.
>>>> </quote>
>>>>
>>>> This renders your requirement 2) infeasible with use of custom LEDs
>>>> any fixed algorithm, since the final effect will always heavily depend
>>>
>>> Typo here: s/any fixed/and fixed/
>>>
>>>> on the LED circuit design.
>>>>
>>>>>
>>>>>       2a) LEDs probably slightly change color as they age. That's out of
>>>>>       scope, unless the variation is much greater than on monitors.
>>>>>
>>>>>       2b) Manufacturing differences cause small color variation. Again,
>>>>>       that's out of scope, unless the variation is much greater than on
>>>>>       monitors.
>>>>>
>>>>> Nice to have features:
>>>>>
>>>>> 3) Full range of available colors/intensities should be available to
>>>>> userspace
>>>>>
>>>>> 4) Interface should work well with existing triggers
>>>>>
>>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>>> variations).
>>>>>
>>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>>> should be integer or fixed point
>>>>>
>>>>> Problems:
>>>>>
>>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>>> red/green/blue channels will result in nothing close to white
>>>>> light. In fact, to get white light on N900, blue and green channel's
>>>>> PWM needs to be set pretty low, as in 5%.
>>>>>
>>>>> b) LED class does not define any relation between "brightness" in
>>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>>> of lumens. RGB color model uses even more complex function.
>>>>>
>>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>>> wavelength of light, while CRTs and LCDs produce broader
>>>>> spectrums.
>>>>>
>>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>>
>>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>>> differences will exist for other colors.
>>>>>
>>>>> f) We have existing RGB LEDs represented as three separate
>>>>> monochromatic LEDs in sysfs.
>>>>
>>>> One general question: do you have any solutions in store?
>>>>
>>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>>
>>>
>>
>> I just wanted to point out that there are 4 total devices right now that use the same mapping
>>
>> LP5018, LP5024, LP5030 and the LP5036.
>>
>> I can implement what ever we would like to I just need to know what to design against.
> 
> As you can see from the discussion in this thread it may take some
> time to work out the interface satisfying everyone. I made some design
> proposal, but Pavel had no warm word for it. It would be easier if
> we had more opinions.

I got it from the threads and just the time invested in the FW and HSV.

> 
> How do you feel about using brightness file for setting LEDn_BRIGHTNESS?

I am using that now.  The brightness file will adjust the overall brightness of the LED group
or bank pending on how the LEDs are grouped in the DT file.

> 
> Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
> increasing color lightness (i.e. the pattern presented in the video [0]
> starting from 1:22)?

No unfortunately this is why I introduced the new files to control the individual RGB intensities
so that the designers can set, tune, create color variations or patterns like the video.

The RGB group brightness would be independent based on lighting conditions, enclosures and diffusers.
So you could technically be changing color and overall brightness virtually simultaneously

> 
>> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.
> 
> Do what you deem most suitable for you. We are here only to help
> merging the patches, but keeping in mind that kernel interface once
> introduced must be preserved forever. Therefore we need to do our
> best to make the best possible design decisions.
> 
> [0] https://www.youtube.com/watch?v=qdt-alh8i6E
> 

I understand.  Maybe I can make the files generic to use for either control or individual control.

We can probably define new ABI's until either HSV or DT frameworks get going.  And them make the file presentation
configurable and default to the new files.

-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-07 21:13                               ` Jacek Anaszewski
@ 2019-01-07 21:15                                 ` Dan Murphy
  2019-01-09  6:46                                 ` Vesa Jääskeläinen
  1 sibling, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2019-01-07 21:15 UTC (permalink / raw)
  To: Jacek Anaszewski, Vesa Jääskeläinen, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Jacek

On 1/7/19 3:13 PM, Jacek Anaszewski wrote:
> Hi Vesa,
> 
> On 1/5/19 1:39 AM, Vesa Jääskeläinen wrote:
>> Hi Jacek,
>>
>> On 04/01/2019 23.37, Jacek Anaszewski wrote:
>>> But, aside from that hypothetic issue, we need a solution for
>>> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
>>> via a single register write. How would you propose to address that?
>>
>> You could model it to something like this in device tree:
>>
>> led-module @ <i2c-address> {
>>      compatible = "lp5024";
>>
>>      // There is in hardware setup to use either linear or
>>      // logarithmic scaling:
>>      //enable-logarithmic-brightness;
>>
>>      led0 {
>>          // this will create led instance for LED0 in lp5024
>>          label = "lp-led0";
>>
>>          // This specifies LED number within lp5024
>>          led-index = <0>;   // set output-base as 0*3 == 0
>>
>>          element-red {
>>              // refers to OUT0
>>              output-offset = <0>;
>>          };
>>
>>          element-green {
>>              // refers to OUT1
>>              output-offset = <1>;
>>          };
>>
>>          element-blue {
>>              // refers to OUT2
>>              output-offset = <2>;
>>          };
>>
>>      };
>>
>>      led1 {
>>          // this will create led instance for LED1 in lp5024
>>          label = "lp-led1";
>>
>>          // This specifies LED number within lp5024
>>          led-index = <1>;   // set output-base as 1*3 == 3
>>
>>          element-red {
>>              // refers to OUT3
>>              output-offset = <0>;
>>          };
>>
>>          element-green {
>>              // refers to OUT4
>>              output-offset = <1>;
>>          };
>>
>>          element-blue {
>>              // refers to OUT5
>>              output-offset = <2>;
>>          };
>>
>>      };
>>
>>      bank-led {
>>          // this will create led instance for bank leds in lp5024
>>          label = "lp-bank-led";
>>
>>          // configured bank led configuration
>>          led-index = <2 3 4 5 6 7>;
>>          // As here is list of led-indices this entry is
>>          // assumed to be bank configuration. Bank mode is enable
>>          // for the indices.
>>
>>          // set output-base as BANK A
>>
>>          element-red {
>>              // refers to BANK A
>>              output-offset = <0>;
>>          };
>>
>>          element-green {
>>              // refers to BANK B
>>              output-offset = <1>;
>>          };
>>
>>          element-blue {
>>              // refers to BANK C
>>              output-offset = <2>;
>>          };
>>      };
>> };
>>
>> This would then create three led instances and each led instance has brightness setting and that goes straight to hardware.
>>
>> If one would want to override hardware control for brightness then I suppose you would define in led node something like:
>>
>>      brightness-model = "hsl"
>>
>> This would then pick red, green and blue elements for hsl calculations and others color elements for linear. LED specific hardware brightness would then be either 0 or 0xFF depending if all of LED color elements are zero or not.
>>
>> Would that kind of model work?
> 
> I'd prefer to have single RGB LED device. And your DT design
> is unnecessarily complex and a bit confusing.

+1 to that comment

> 
> Also, you provided scarce information about sysfs interface.
> It would be nice to see the sequence of commands.
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2018-12-19 16:26 ` [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver Dan Murphy
  2018-12-28 23:53   ` Rob Herring
@ 2019-01-08 20:33   ` Jacek Anaszewski
  2019-01-08 20:53     ` Dan Murphy
  1 sibling, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-08 20:33 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Dan,

On 12/19/18 5:26 PM, Dan Murphy wrote:
> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
> or as part of a control bank group.  These devices have the ability
> to adjust the mixing control for the RGB LEDs to obtain different colors
> independent of the overall brightness of the LED grouping.
> 
> Datasheet:
> http://www.ti.com/lit/ds/symlink/lp5024.pdf
> 
> Signed-off-by: Dan Murphy <dmurphy@ti.com>
> ---
>   .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>   1 file changed, 63 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
> 
> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
> new file mode 100644
> index 000000000000..9567aa6f7813
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
> @@ -0,0 +1,63 @@
> +* Texas Instruments - LP5024/18 RGB LED driver
> +
> +The LM3692x is an ultra-compact, highly efficient,
> +white-LED driver designed for LCD display backlighting.
> +
> +The main difference between the LP5024 and L5018 is the number of
> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
> +LP5018 supports eighteen strings.
> +
> +Required properties:
> +	- compatible:
> +		"ti,lp5018"
> +		"ti,lp5024"
> +	- reg :  I2C slave address
> +	- #address-cells : 1
> +	- #size-cells : 0
> +
> +Optional properties:
> +	- enable-gpios : gpio pin to enable/disable the device.
> +	- vled-supply : LED supply
> +
> +Required child properties:
> +	- reg : Is the child node iteration.
> +	- led-sources : LP5024 - 0 - 7
> +			LP5018 - 0 - 5
> +			Declares the LED string or strings that the child node
> +			will control.  If ti,control-bank is set then this
> +			property will contain multiple LED IDs.
> +
> +Optional child properties:
> +	- label : see Documentation/devicetree/bindings/leds/common.txt
> +	- linux,default-trigger :
> +	   see Documentation/devicetree/bindings/leds/common.txt
> +	- ti,control-bank : Indicates that the LED strings declared in the
> +			    led-sources property are grouped within a control
> +			    bank for brightness and mixing control.
> +
> +Example:
> +
> +led-controller@28 {
> +	compatible = "ti,lp5024";
> +	reg = <0x28>;
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
> +	vled-supply = <&vbatt>;
> +
> +	led@0 {
> +		reg = <0>;
> +		led-sources = <1>;
> +	};
> +
> +	led@1 {
> +		reg = <1>;
> +		led-sources = <0 6>;
> +		ti,control-bank;

Do you really need ti,control-bank? Doesn't led-sources array size
greater than 1 mean that the node describes control bank?

Also, does it make sense to have only two LEDs in the bank?

> +	};
> +
> +}
> +
> +For more product information please see the link below:
> +http://www.ti.com/lit/ds/symlink/lp5024.pdf
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-08 20:33   ` Jacek Anaszewski
@ 2019-01-08 20:53     ` Dan Murphy
  2019-01-08 21:16       ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-08 20:53 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
> Dan,
> 
> On 12/19/18 5:26 PM, Dan Murphy wrote:
>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>> or as part of a control bank group.  These devices have the ability
>> to adjust the mixing control for the RGB LEDs to obtain different colors
>> independent of the overall brightness of the LED grouping.
>>
>> Datasheet:
>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>
>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>> ---
>>   .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>   1 file changed, 63 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>
>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>> new file mode 100644
>> index 000000000000..9567aa6f7813
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>> @@ -0,0 +1,63 @@
>> +* Texas Instruments - LP5024/18 RGB LED driver
>> +
>> +The LM3692x is an ultra-compact, highly efficient,
>> +white-LED driver designed for LCD display backlighting.
>> +
>> +The main difference between the LP5024 and L5018 is the number of
>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>> +LP5018 supports eighteen strings.
>> +
>> +Required properties:
>> +    - compatible:
>> +        "ti,lp5018"
>> +        "ti,lp5024"
>> +    - reg :  I2C slave address
>> +    - #address-cells : 1
>> +    - #size-cells : 0
>> +
>> +Optional properties:
>> +    - enable-gpios : gpio pin to enable/disable the device.
>> +    - vled-supply : LED supply
>> +
>> +Required child properties:
>> +    - reg : Is the child node iteration.
>> +    - led-sources : LP5024 - 0 - 7
>> +            LP5018 - 0 - 5
>> +            Declares the LED string or strings that the child node
>> +            will control.  If ti,control-bank is set then this
>> +            property will contain multiple LED IDs.
>> +
>> +Optional child properties:
>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>> +    - linux,default-trigger :
>> +       see Documentation/devicetree/bindings/leds/common.txt
>> +    - ti,control-bank : Indicates that the LED strings declared in the
>> +                led-sources property are grouped within a control
>> +                bank for brightness and mixing control.
>> +
>> +Example:
>> +
>> +led-controller@28 {
>> +    compatible = "ti,lp5024";
>> +    reg = <0x28>;
>> +    #address-cells = <1>;
>> +    #size-cells = <0>;
>> +
>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>> +    vled-supply = <&vbatt>;
>> +
>> +    led@0 {
>> +        reg = <0>;
>> +        led-sources = <1>;
>> +    };
>> +
>> +    led@1 {
>> +        reg = <1>;
>> +        led-sources = <0 6>;
>> +        ti,control-bank;
> 
> Do you really need ti,control-bank? Doesn't led-sources array size
> greater than 1 mean that the node describes control bank?
> 

That will work too.

> Also, does it make sense to have only two LEDs in the bank?

The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
See the description above of the led-sources


Dan

> 
>> +    };
>> +
>> +}
>> +
>> +For more product information please see the link below:
>> +http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2018-12-19 16:26 ` [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver Dan Murphy
  2018-12-19 19:04   ` Dan Murphy
  2018-12-19 19:34   ` Pavel Machek
@ 2019-01-08 21:10   ` Jacek Anaszewski
  2019-01-08 21:17     ` Dan Murphy
  2 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-08 21:10 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Dan,

On 12/19/18 5:26 PM, Dan Murphy wrote:
> Introduce the LP5024 and LP5018 RGB LED driver.
> The difference in these 2 parts are only in the number of
> LED outputs where the LP5024 can control 24 LEDs the LP5018
> can only control 18.
> 
> The device has the ability to group LED output into control banks
> so that multiple LED banks can be controlled with the same mixing and
> brightness.  Inversely the LEDs can also be controlled independently.
> 
> Signed-off-by: Dan Murphy <dmurphy@ti.com>
> ---
>   drivers/leds/Kconfig       |   7 +
>   drivers/leds/Makefile      |   1 +
>   drivers/leds/leds-lp5024.c | 610 +++++++++++++++++++++++++++++++++++++
>   3 files changed, 618 insertions(+)
>   create mode 100644 drivers/leds/leds-lp5024.c
> 
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index a72f97fca57b..d306bedb00b7 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -326,6 +326,13 @@ config LEDS_LP3952
>   	  To compile this driver as a module, choose M here: the
>   	  module will be called leds-lp3952.
>   
> +config LEDS_LP5024
> +	tristate "LED Support for TI LP5024/18 LED driver chip"
> +	depends on LEDS_CLASS && REGMAP_I2C
> +	help
> +	  If you say yes here you get support for the Texas Instruments
> +	  LP5024 and LP5018 LED driver.
> +
>   config LEDS_LP55XX_COMMON
>   	tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501"
>   	depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501
> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
> index 4c1b0054f379..60b4e4ddd3ee 100644
> --- a/drivers/leds/Makefile
> +++ b/drivers/leds/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_LEDS_GPIO_REGISTER)	+= leds-gpio-register.o
>   obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
>   obj-$(CONFIG_LEDS_LP3944)		+= leds-lp3944.o
>   obj-$(CONFIG_LEDS_LP3952)		+= leds-lp3952.o
> +obj-$(CONFIG_LEDS_LP5024)		+= leds-lp5024.o
>   obj-$(CONFIG_LEDS_LP55XX_COMMON)	+= leds-lp55xx-common.o
>   obj-$(CONFIG_LEDS_LP5521)		+= leds-lp5521.o
>   obj-$(CONFIG_LEDS_LP5523)		+= leds-lp5523.o
> diff --git a/drivers/leds/leds-lp5024.c b/drivers/leds/leds-lp5024.c
> new file mode 100644
> index 000000000000..90e8dca15609
> --- /dev/null
> +++ b/drivers/leds/leds-lp5024.c
> @@ -0,0 +1,610 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* TI LP50XX LED chip family driver
> + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
> + */
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/init.h>
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <uapi/linux/uleds.h>
> +
> +#define LP5024_DEV_CFG0		0x00
> +#define LP5024_DEV_CFG1		0x01
> +#define LP5024_LED_CFG0		0x02
> +#define LP5024_BNK_BRT		0x03
> +#define LP5024_BNKA_CLR		0x04
> +#define LP5024_BNKB_CLR		0x05
> +#define LP5024_BNKC_CLR		0x06
> +#define LP5024_LED0_BRT		0x07
> +#define LP5024_LED1_BRT		0x08
> +#define LP5024_LED2_BRT		0x09
> +#define LP5024_LED3_BRT		0x0a
> +#define LP5024_LED4_BRT		0x0b
> +#define LP5024_LED5_BRT		0x0c
> +#define LP5024_LED6_BRT		0x0d
> +#define LP5024_LED7_BRT		0x0e
> +
> +#define LP5024_OUT0_CLR		0x0f
> +#define LP5024_OUT1_CLR		0x10
> +#define LP5024_OUT2_CLR		0x11
> +#define LP5024_OUT3_CLR		0x12
> +#define LP5024_OUT4_CLR		0x13
> +#define LP5024_OUT5_CLR		0x14
> +#define LP5024_OUT6_CLR		0x15
> +#define LP5024_OUT7_CLR		0x16
> +#define LP5024_OUT8_CLR		0x17
> +#define LP5024_OUT9_CLR		0x18
> +#define LP5024_OUT10_CLR	0x19
> +#define LP5024_OUT11_CLR	0x1a
> +#define LP5024_OUT12_CLR	0x1b
> +#define LP5024_OUT13_CLR	0x1c
> +#define LP5024_OUT14_CLR	0x1d
> +#define LP5024_OUT15_CLR	0x1e
> +#define LP5024_OUT16_CLR	0x1f
> +#define LP5024_OUT17_CLR	0x20
> +#define LP5024_OUT18_CLR	0x21
> +#define LP5024_OUT19_CLR	0x22
> +#define LP5024_OUT20_CLR	0x23
> +#define LP5024_OUT21_CLR	0x24
> +#define LP5024_OUT22_CLR	0x25
> +#define LP5024_OUT23_CLR	0x26
> +
> +#define LP5024_RESET		0x27
> +#define LP5024_SW_RESET		0xff
> +
> +#define LP5024_CHIP_EN		BIT(6)
> +
> +#define LP5024_CONTROL_A		0
> +#define LP5024_CONTROL_B		1
> +#define LP5024_CONTROL_C		2
> +#define LP5024_MAX_CONTROL_BANKS	3
> +
> +#define LP5018_MAX_LED_STRINGS	6
> +#define LP5024_MAX_LED_STRINGS	8
> +
> +enum lp5024_model {
> +	LP5018,
> +	LP5024,
> +};
> +
> +struct lp5024_led {
> +	u32 led_strings[LP5024_MAX_LED_STRINGS];
> +	char label[LED_MAX_NAME_SIZE];
> +	struct led_classdev led_dev;
> +	struct lp5024 *priv;
> +	int led_number;
> +	u8 ctrl_bank_enabled;
> +};
> +
> +/**
> + * struct lp5024 -
> + * @enable_gpio: Hardware enable gpio
> + * @regulator: LED supply regulator pointer
> + * @client: Pointer to the I2C client
> + * @regmap: Devices register map
> + * @dev: Pointer to the devices device struct
> + * @lock: Lock for reading/writing the device
> + * @model_id: ID of the device
> + * @leds: Array of LED strings
> + */
> +struct lp5024 {
> +	struct gpio_desc *enable_gpio;
> +	struct regulator *regulator;
> +	struct i2c_client *client;
> +	struct regmap *regmap;
> +	struct device *dev;
> +	struct mutex lock;
> +	int model_id;
> +	int max_leds;
> +	int num_of_leds;
> +
> +	/* This needs to be at the end of the struct */
> +	struct lp5024_led leds[];
> +};
> +
> +static const struct reg_default lp5024_reg_defs[] = {
> +	{LP5024_DEV_CFG0, 0x0},
> +	{LP5024_DEV_CFG1, 0x3c},
> +	{LP5024_BNK_BRT, 0xff},
> +	{LP5024_BNKA_CLR, 0x0f},
> +	{LP5024_BNKB_CLR, 0x0f},
> +	{LP5024_BNKC_CLR, 0x0f},
> +	{LP5024_LED0_BRT, 0x0f},
> +	{LP5024_LED1_BRT, 0xff},
> +	{LP5024_LED2_BRT, 0xff},
> +	{LP5024_LED3_BRT, 0xff},
> +	{LP5024_LED4_BRT, 0xff},
> +	{LP5024_LED5_BRT, 0xff},
> +	{LP5024_LED6_BRT, 0xff},
> +	{LP5024_LED7_BRT, 0xff},
> +	{LP5024_OUT0_CLR, 0x0f},
> +	{LP5024_OUT1_CLR, 0x00},
> +	{LP5024_OUT2_CLR, 0x00},
> +	{LP5024_OUT3_CLR, 0x00},
> +	{LP5024_OUT4_CLR, 0x00},
> +	{LP5024_OUT5_CLR, 0x00},
> +	{LP5024_OUT6_CLR, 0x00},
> +	{LP5024_OUT7_CLR, 0x00},
> +	{LP5024_OUT8_CLR, 0x00},
> +	{LP5024_OUT9_CLR, 0x00},
> +	{LP5024_OUT10_CLR, 0x00},
> +	{LP5024_OUT11_CLR, 0x00},
> +	{LP5024_OUT12_CLR, 0x00},
> +	{LP5024_OUT13_CLR, 0x00},
> +	{LP5024_OUT14_CLR, 0x00},
> +	{LP5024_OUT15_CLR, 0x00},
> +	{LP5024_OUT16_CLR, 0x00},
> +	{LP5024_OUT17_CLR, 0x00},
> +	{LP5024_OUT18_CLR, 0x00},
> +	{LP5024_OUT19_CLR, 0x00},
> +	{LP5024_OUT20_CLR, 0x00},
> +	{LP5024_OUT21_CLR, 0x00},
> +	{LP5024_OUT22_CLR, 0x00},
> +	{LP5024_OUT23_CLR, 0x00},
> +	{LP5024_RESET, 0x00}
> +};
> +
> +static const struct regmap_config lp5024_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +
> +	.max_register = LP5024_RESET,
> +	.reg_defaults = lp5024_reg_defs,
> +	.num_reg_defaults = ARRAY_SIZE(lp5024_reg_defs),
> +	.cache_type = REGCACHE_RBTREE,
> +};
> +
> +static int lp5024_set_color_mix(struct lp5024_led *led, u8 color_reg,
> +				u8 color_val)
> +{
> +	return regmap_write(led->priv->regmap, color_reg, color_val);
> +}
> +
> +
> +static ssize_t ctrl_bank_a_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	lp5024_set_color_mix(led, LP5024_BNKA_CLR, mix_value);
> +
> +	return size;
> +}
> +static ssize_t ctrl_bank_b_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	lp5024_set_color_mix(led, LP5024_BNKB_CLR, mix_value);
> +
> +	return size;
> +}
> +static ssize_t ctrl_bank_c_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	lp5024_set_color_mix(led, LP5024_BNKC_CLR, mix_value);
> +
> +	return size;
> +}
> +
> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);

Why WO?

> +
> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
> +	&dev_attr_ctrl_bank_a_mix.attr,
> +	&dev_attr_ctrl_bank_b_mix.attr,
> +	&dev_attr_ctrl_bank_c_mix.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
> +
> +static ssize_t led3_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	u8 reg_value; > +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	reg_value = (led->led_number * 3) + LP5024_OUT2_CLR;

It is more natural if constant goes first. Like BASE_ADDR + offset.

> +
> +	lp5024_set_color_mix(led, reg_value, mix_value);
> +
> +	return size;
> +}
> +
> +static ssize_t led2_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	u8 reg_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	reg_value = (led->led_number * 3) + LP5024_OUT1_CLR;
> +
> +	lp5024_set_color_mix(led, reg_value, mix_value);
> +
> +	return size;
> +}
> +
> +static ssize_t led1_mix_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf, size_t size)
> +{
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	u8 mix_value;
> +	u8 reg_value;
> +	int ret;
> +
> +	ret = kstrtou8(buf, 0, &mix_value);
> +	if (ret)
> +		return ret;
> +
> +	reg_value = (led->led_number * 3) + LP5024_OUT0_CLR;
> +
> +	lp5024_set_color_mix(led, reg_value, mix_value);
> +
> +	return size;
> +}
> +
> +static DEVICE_ATTR_WO(led1_mix);
> +static DEVICE_ATTR_WO(led2_mix);
> +static DEVICE_ATTR_WO(led3_mix);

Why WO?

> +static struct attribute *lp5024_led_independent_attrs[] = {
> +	&dev_attr_led1_mix.attr,
> +	&dev_attr_led2_mix.attr,
> +	&dev_attr_led3_mix.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(lp5024_led_independent);
> +
> +static int lp5024_brightness_set(struct led_classdev *led_cdev,
> +				enum led_brightness brt_val)
> +{
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	int ret = 0;
> +	u8 reg_val;
> +
> +	mutex_lock(&led->priv->lock);
> +
> +	if (led->ctrl_bank_enabled)
> +		reg_val = LP5024_BNK_BRT;
> +	else
> +		reg_val = led->led_number + LP5024_LED0_BRT;
> +
> +	ret = regmap_write(led->priv->regmap, reg_val, brt_val);
> +
> +	mutex_unlock(&led->priv->lock);
> +
> +	return ret;
> +}
> +
> +static enum led_brightness lp5024_brightness_get(struct led_classdev *led_cdev)
> +{
> +	struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
> +					      led_dev);
> +	unsigned int brt_val;
> +	u8 reg_val;
> +	int ret;
> +
> +	mutex_lock(&led->priv->lock);
> +
> +	if (led->ctrl_bank_enabled)
> +		reg_val = LP5024_BNK_BRT;
> +	else
> +		reg_val = led->led_number + LP5024_LED0_BRT;
> +
> +	ret = regmap_read(led->priv->regmap, reg_val, &brt_val);
> +
> +	mutex_unlock(&led->priv->lock);
> +
> +	return brt_val;
> +}
> +
> +static int lp5024_set_led_values(struct lp5024 *priv)
> +{
> +	struct lp5024_led *led;
> +	int i, j;
> +	u8 led_ctrl_enable = 0;
> +
> +	for (i = 0; i <= priv->num_of_leds; i++) {
> +		led = &priv->leds[i];
> +		if (led->ctrl_bank_enabled) {
> +			for (j = 0; j <= LP5024_MAX_LED_STRINGS - 1; j++)
> +				led_ctrl_enable |= (1 << led->led_strings[j]);
> +		}
> +	}
> +
> +	regmap_write(priv->regmap, LP5024_LED_CFG0, led_ctrl_enable);
> +
> +	return 0;
> +}
> +
> +static int lp5024_init(struct lp5024 *priv)
> +{
> +	int ret;
> +
> +	if (priv->enable_gpio) {
> +		gpiod_direction_output(priv->enable_gpio, 1);
> +	} else {
> +		ret = regmap_write(priv->regmap, LP5024_RESET, LP5024_SW_RESET);
> +		if (ret) {
> +			dev_err(&priv->client->dev,
> +				"Cannot reset the device\n");
> +			goto out;
> +		}
> +	}
> +
> +	ret = lp5024_set_led_values(priv);
> +	if (ret)
> +		dev_err(&priv->client->dev, "Setting the CRTL bank failed\n");
> +
> +	ret = regmap_write(priv->regmap, LP5024_DEV_CFG0, LP5024_CHIP_EN);
> +	if (ret) {
> +		dev_err(&priv->client->dev, "Cannot write ctrl enable\n");
> +		goto out;
> +	}
> +out:
> +	return ret;
> +}
> +
> +static int lp5024_probe_dt(struct lp5024 *priv)
> +{
> +	struct fwnode_handle *child = NULL;
> +	struct lp5024_led *led;
> +	const char *name;
> +	int led_number;
> +	size_t i = 0;
> +	int ret;
> +
> +	priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
> +						   "enable", GPIOD_OUT_LOW);
> +	if (IS_ERR(priv->enable_gpio)) {
> +		ret = PTR_ERR(priv->enable_gpio);
> +		dev_err(&priv->client->dev, "Failed to get enable gpio: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	priv->regulator = devm_regulator_get(&priv->client->dev, "vled");
> +	if (IS_ERR(priv->regulator))
> +		priv->regulator = NULL;
> +
> +	if (priv->model_id == LP5018)
> +		priv->max_leds = LP5018_MAX_LED_STRINGS;
> +	else
> +		priv->max_leds = LP5024_MAX_LED_STRINGS;
> +
> +	device_for_each_child_node(&priv->client->dev, child) {
> +		led = &priv->leds[i];
> +
> +		if (fwnode_property_present(child, "ti,control-bank"))
> +			led->ctrl_bank_enabled = 1;
> +		else
> +			led->ctrl_bank_enabled = 0;
> +
> +		if (led->ctrl_bank_enabled) {
> +			ret = fwnode_property_read_u32_array(child,
> +							     "led-sources",
> +							     NULL, 0);
> +			ret = fwnode_property_read_u32_array(child,
> +							     "led-sources",
> +							     led->led_strings,
> +							     ret);
> +
> +			led->led_number = led->led_strings[0];
> +
> +		} else {
> +			ret = fwnode_property_read_u32(child, "led-sources",
> +					       &led_number);
> +
> +			led->led_number = led_number;
> +		}
> +		if (ret) {
> +			dev_err(&priv->client->dev,
> +				"led-sources property missing\n");
> +			fwnode_handle_put(child);
> +			goto child_out;
> +		}
> +
> +		if (led_number > priv->max_leds) {
> +			dev_err(&priv->client->dev,
> +				"led-sources property is invalid\n");
> +			ret = -EINVAL;
> +			fwnode_handle_put(child);
> +			goto child_out;
> +		}
> +
> +		ret = fwnode_property_read_string(child, "label", &name);
> +		if (ret)
> +			snprintf(led->label, sizeof(led->label),
> +				"%s::", priv->client->name);
> +		else
> +			snprintf(led->label, sizeof(led->label),
> +				 "%s:%s", priv->client->name, name);
> +
> +		fwnode_property_read_string(child, "linux,default-trigger",
> +				    &led->led_dev.default_trigger);
> +
> +		led->priv = priv;
> +		led->led_dev.name = led->label;
> +		led->led_dev.max_brightness = 255;
> +		led->led_dev.brightness_set_blocking = lp5024_brightness_set;
> +		led->led_dev.brightness_get = lp5024_brightness_get;
> +
> +		if (led->ctrl_bank_enabled)
> +			led->led_dev.groups = lp5024_ctrl_bank_groups;
> +		else
> +			led->led_dev.groups = lp5024_led_independent_groups;
> +
> +		ret = devm_led_classdev_register(&priv->client->dev,
> +						 &led->led_dev);
> +		if (ret) {
> +			dev_err(&priv->client->dev, "led register err: %d\n",
> +				ret);
> +			fwnode_handle_put(child);
> +			goto child_out;
> +		}
> +		i++;
> +	}
> +	priv->num_of_leds = i;
> +
> +child_out:
> +	return ret;
> +}
> +
> +static int lp5024_probe(struct i2c_client *client,
> +			const struct i2c_device_id *id)
> +{
> +	struct lp5024 *led;
> +	int count;
> +	int ret;
> +
> +	count = device_get_child_node_count(&client->dev);
> +	if (!count) {
> +		dev_err(&client->dev, "LEDs are not defined in device tree!");
> +		return -ENODEV;
> +	}
> +
> +	led = devm_kzalloc(&client->dev, struct_size(led, leds, count),
> +			   GFP_KERNEL);
> +	if (!led)
> +		return -ENOMEM;
> +
> +	mutex_init(&led->lock);
> +	led->client = client;
> +	led->dev = &client->dev;
> +	led->model_id = id->driver_data;
> +	i2c_set_clientdata(client, led);
> +
> +	led->regmap = devm_regmap_init_i2c(client, &lp5024_regmap_config);
> +	if (IS_ERR(led->regmap)) {
> +		ret = PTR_ERR(led->regmap);
> +		dev_err(&client->dev, "Failed to allocate register map: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	ret = lp5024_probe_dt(led);
> +	if (ret)
> +		return ret;
> +
> +	ret = lp5024_init(led);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int lp5024_remove(struct i2c_client *client)
> +{
> +	struct lp5024 *led = i2c_get_clientdata(client);
> +	int ret;
> +
> +	ret = regmap_update_bits(led->regmap, LP5024_DEV_CFG0,
> +				 LP5024_CHIP_EN, 0);
> +	if (ret) {
> +		dev_err(&led->client->dev, "Failed to disable regulator\n");
> +		return ret;
> +	}
> +
> +	if (led->enable_gpio)
> +		gpiod_direction_output(led->enable_gpio, 0);
> +
> +	if (led->regulator) {
> +		ret = regulator_disable(led->regulator);
> +		if (ret)
> +			dev_err(&led->client->dev,
> +				"Failed to disable regulator\n");
> +	}
> +
> +	mutex_destroy(&led->lock);
> +
> +	return 0;
> +}
> +
> +static const struct i2c_device_id lp5024_id[] = {
> +	{ "lp5018", LP5018 },
> +	{ "lp5024", LP5024 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, lp5024_id);
> +
> +static const struct of_device_id of_lp5024_leds_match[] = {
> +	{ .compatible = "ti,lp5018", },
> +	{ .compatible = "ti,lp5024", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, of_lp5024_leds_match);
> +
> +static struct i2c_driver lp5024_driver = {
> +	.driver = {
> +		.name	= "lp5024",
> +		.of_match_table = of_lp5024_leds_match,
> +	},
> +	.probe		= lp5024_probe,
> +	.remove		= lp5024_remove,
> +	.id_table	= lp5024_id,
> +};
> +module_i2c_driver(lp5024_driver);
> +
> +MODULE_DESCRIPTION("Texas Instruments LP5024 LED driver");
> +MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
> +MODULE_LICENSE("GPL v2");
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-08 20:53     ` Dan Murphy
@ 2019-01-08 21:16       ` Jacek Anaszewski
  2019-01-08 21:22         ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-08 21:16 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

On 1/8/19 9:53 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>> Dan,
>>
>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>> or as part of a control bank group.  These devices have the ability
>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>> independent of the overall brightness of the LED grouping.
>>>
>>> Datasheet:
>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>
>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>> ---
>>>    .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>    1 file changed, 63 insertions(+)
>>>    create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>> new file mode 100644
>>> index 000000000000..9567aa6f7813
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>> @@ -0,0 +1,63 @@
>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>> +
>>> +The LM3692x is an ultra-compact, highly efficient,
>>> +white-LED driver designed for LCD display backlighting.
>>> +
>>> +The main difference between the LP5024 and L5018 is the number of
>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>> +LP5018 supports eighteen strings.
>>> +
>>> +Required properties:
>>> +    - compatible:
>>> +        "ti,lp5018"
>>> +        "ti,lp5024"
>>> +    - reg :  I2C slave address
>>> +    - #address-cells : 1
>>> +    - #size-cells : 0
>>> +
>>> +Optional properties:
>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>> +    - vled-supply : LED supply
>>> +
>>> +Required child properties:
>>> +    - reg : Is the child node iteration.
>>> +    - led-sources : LP5024 - 0 - 7
>>> +            LP5018 - 0 - 5
>>> +            Declares the LED string or strings that the child node
>>> +            will control.  If ti,control-bank is set then this
>>> +            property will contain multiple LED IDs.
>>> +
>>> +Optional child properties:
>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>> +    - linux,default-trigger :
>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>> +                led-sources property are grouped within a control
>>> +                bank for brightness and mixing control.
>>> +
>>> +Example:
>>> +
>>> +led-controller@28 {
>>> +    compatible = "ti,lp5024";
>>> +    reg = <0x28>;
>>> +    #address-cells = <1>;
>>> +    #size-cells = <0>;
>>> +
>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>> +    vled-supply = <&vbatt>;
>>> +
>>> +    led@0 {
>>> +        reg = <0>;
>>> +        led-sources = <1>;
>>> +    };
>>> +
>>> +    led@1 {
>>> +        reg = <1>;
>>> +        led-sources = <0 6>;
>>> +        ti,control-bank;
>>
>> Do you really need ti,control-bank? Doesn't led-sources array size
>> greater than 1 mean that the node describes control bank?
>>
> 
> That will work too.

>> Also, does it make sense to have only two LEDs in the bank?
> 
> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
> See the description above of the led-sources

OK, I confused RGB LED modules with banks.

Shouldn't we allow for defining either strings or RGB LED
triplets somehow then?

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-08 21:10   ` Jacek Anaszewski
@ 2019-01-08 21:17     ` Dan Murphy
  0 siblings, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2019-01-08 21:17 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

Thanks for the review.  v2 will contain the LP5030/36 as well.

On 1/8/19 3:10 PM, Jacek Anaszewski wrote:
> Dan,
> 
> On 12/19/18 5:26 PM, Dan Murphy wrote:
>> Introduce the LP5024 and LP5018 RGB LED driver.
>> The difference in these 2 parts are only in the number of
>> LED outputs where the LP5024 can control 24 LEDs the LP5018
>> can only control 18.
>>
>> The device has the ability to group LED output into control banks
>> so that multiple LED banks can be controlled with the same mixing and
>> brightness.  Inversely the LEDs can also be controlled independently.
>>
>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>> ---
>>   drivers/leds/Kconfig       |   7 +
>>   drivers/leds/Makefile      |   1 +
>>   drivers/leds/leds-lp5024.c | 610 +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 618 insertions(+)
>>   create mode 100644 drivers/leds/leds-lp5024.c
>>
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index a72f97fca57b..d306bedb00b7 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -326,6 +326,13 @@ config LEDS_LP3952
>>         To compile this driver as a module, choose M here: the
>>         module will be called leds-lp3952.
>>   +config LEDS_LP5024
>> +    tristate "LED Support for TI LP5024/18 LED driver chip"
>> +    depends on LEDS_CLASS && REGMAP_I2C
>> +    help
>> +      If you say yes here you get support for the Texas Instruments
>> +      LP5024 and LP5018 LED driver.
>> +
>>   config LEDS_LP55XX_COMMON
>>       tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501"
>>       depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501
>> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
>> index 4c1b0054f379..60b4e4ddd3ee 100644
>> --- a/drivers/leds/Makefile
>> +++ b/drivers/leds/Makefile
>> @@ -32,6 +32,7 @@ obj-$(CONFIG_LEDS_GPIO_REGISTER)    += leds-gpio-register.o
>>   obj-$(CONFIG_LEDS_GPIO)            += leds-gpio.o
>>   obj-$(CONFIG_LEDS_LP3944)        += leds-lp3944.o
>>   obj-$(CONFIG_LEDS_LP3952)        += leds-lp3952.o
>> +obj-$(CONFIG_LEDS_LP5024)        += leds-lp5024.o
>>   obj-$(CONFIG_LEDS_LP55XX_COMMON)    += leds-lp55xx-common.o
>>   obj-$(CONFIG_LEDS_LP5521)        += leds-lp5521.o
>>   obj-$(CONFIG_LEDS_LP5523)        += leds-lp5523.o
>> diff --git a/drivers/leds/leds-lp5024.c b/drivers/leds/leds-lp5024.c
>> new file mode 100644
>> index 000000000000..90e8dca15609
>> --- /dev/null
>> +++ b/drivers/leds/leds-lp5024.c
>> @@ -0,0 +1,610 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* TI LP50XX LED chip family driver
>> + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
>> + */
>> +
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/i2c.h>
>> +#include <linux/init.h>
>> +#include <linux/leds.h>
>> +#include <linux/module.h>
>> +#include <linux/mutex.h>
>> +#include <linux/of.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/regmap.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/slab.h>
>> +#include <uapi/linux/uleds.h>
>> +
>> +#define LP5024_DEV_CFG0        0x00
>> +#define LP5024_DEV_CFG1        0x01
>> +#define LP5024_LED_CFG0        0x02
>> +#define LP5024_BNK_BRT        0x03
>> +#define LP5024_BNKA_CLR        0x04
>> +#define LP5024_BNKB_CLR        0x05
>> +#define LP5024_BNKC_CLR        0x06
>> +#define LP5024_LED0_BRT        0x07
>> +#define LP5024_LED1_BRT        0x08
>> +#define LP5024_LED2_BRT        0x09
>> +#define LP5024_LED3_BRT        0x0a
>> +#define LP5024_LED4_BRT        0x0b
>> +#define LP5024_LED5_BRT        0x0c
>> +#define LP5024_LED6_BRT        0x0d
>> +#define LP5024_LED7_BRT        0x0e
>> +
>> +#define LP5024_OUT0_CLR        0x0f
>> +#define LP5024_OUT1_CLR        0x10
>> +#define LP5024_OUT2_CLR        0x11
>> +#define LP5024_OUT3_CLR        0x12
>> +#define LP5024_OUT4_CLR        0x13
>> +#define LP5024_OUT5_CLR        0x14
>> +#define LP5024_OUT6_CLR        0x15
>> +#define LP5024_OUT7_CLR        0x16
>> +#define LP5024_OUT8_CLR        0x17
>> +#define LP5024_OUT9_CLR        0x18
>> +#define LP5024_OUT10_CLR    0x19
>> +#define LP5024_OUT11_CLR    0x1a
>> +#define LP5024_OUT12_CLR    0x1b
>> +#define LP5024_OUT13_CLR    0x1c
>> +#define LP5024_OUT14_CLR    0x1d
>> +#define LP5024_OUT15_CLR    0x1e
>> +#define LP5024_OUT16_CLR    0x1f
>> +#define LP5024_OUT17_CLR    0x20
>> +#define LP5024_OUT18_CLR    0x21
>> +#define LP5024_OUT19_CLR    0x22
>> +#define LP5024_OUT20_CLR    0x23
>> +#define LP5024_OUT21_CLR    0x24
>> +#define LP5024_OUT22_CLR    0x25
>> +#define LP5024_OUT23_CLR    0x26
>> +
>> +#define LP5024_RESET        0x27
>> +#define LP5024_SW_RESET        0xff
>> +
>> +#define LP5024_CHIP_EN        BIT(6)
>> +
>> +#define LP5024_CONTROL_A        0
>> +#define LP5024_CONTROL_B        1
>> +#define LP5024_CONTROL_C        2
>> +#define LP5024_MAX_CONTROL_BANKS    3
>> +
>> +#define LP5018_MAX_LED_STRINGS    6
>> +#define LP5024_MAX_LED_STRINGS    8
>> +
>> +enum lp5024_model {
>> +    LP5018,
>> +    LP5024,
>> +};
>> +
>> +struct lp5024_led {
>> +    u32 led_strings[LP5024_MAX_LED_STRINGS];
>> +    char label[LED_MAX_NAME_SIZE];
>> +    struct led_classdev led_dev;
>> +    struct lp5024 *priv;
>> +    int led_number;
>> +    u8 ctrl_bank_enabled;
>> +};
>> +
>> +/**
>> + * struct lp5024 -
>> + * @enable_gpio: Hardware enable gpio
>> + * @regulator: LED supply regulator pointer
>> + * @client: Pointer to the I2C client
>> + * @regmap: Devices register map
>> + * @dev: Pointer to the devices device struct
>> + * @lock: Lock for reading/writing the device
>> + * @model_id: ID of the device
>> + * @leds: Array of LED strings
>> + */
>> +struct lp5024 {
>> +    struct gpio_desc *enable_gpio;
>> +    struct regulator *regulator;
>> +    struct i2c_client *client;
>> +    struct regmap *regmap;
>> +    struct device *dev;
>> +    struct mutex lock;
>> +    int model_id;
>> +    int max_leds;
>> +    int num_of_leds;
>> +
>> +    /* This needs to be at the end of the struct */
>> +    struct lp5024_led leds[];
>> +};
>> +
>> +static const struct reg_default lp5024_reg_defs[] = {
>> +    {LP5024_DEV_CFG0, 0x0},
>> +    {LP5024_DEV_CFG1, 0x3c},
>> +    {LP5024_BNK_BRT, 0xff},
>> +    {LP5024_BNKA_CLR, 0x0f},
>> +    {LP5024_BNKB_CLR, 0x0f},
>> +    {LP5024_BNKC_CLR, 0x0f},
>> +    {LP5024_LED0_BRT, 0x0f},
>> +    {LP5024_LED1_BRT, 0xff},
>> +    {LP5024_LED2_BRT, 0xff},
>> +    {LP5024_LED3_BRT, 0xff},
>> +    {LP5024_LED4_BRT, 0xff},
>> +    {LP5024_LED5_BRT, 0xff},
>> +    {LP5024_LED6_BRT, 0xff},
>> +    {LP5024_LED7_BRT, 0xff},
>> +    {LP5024_OUT0_CLR, 0x0f},
>> +    {LP5024_OUT1_CLR, 0x00},
>> +    {LP5024_OUT2_CLR, 0x00},
>> +    {LP5024_OUT3_CLR, 0x00},
>> +    {LP5024_OUT4_CLR, 0x00},
>> +    {LP5024_OUT5_CLR, 0x00},
>> +    {LP5024_OUT6_CLR, 0x00},
>> +    {LP5024_OUT7_CLR, 0x00},
>> +    {LP5024_OUT8_CLR, 0x00},
>> +    {LP5024_OUT9_CLR, 0x00},
>> +    {LP5024_OUT10_CLR, 0x00},
>> +    {LP5024_OUT11_CLR, 0x00},
>> +    {LP5024_OUT12_CLR, 0x00},
>> +    {LP5024_OUT13_CLR, 0x00},
>> +    {LP5024_OUT14_CLR, 0x00},
>> +    {LP5024_OUT15_CLR, 0x00},
>> +    {LP5024_OUT16_CLR, 0x00},
>> +    {LP5024_OUT17_CLR, 0x00},
>> +    {LP5024_OUT18_CLR, 0x00},
>> +    {LP5024_OUT19_CLR, 0x00},
>> +    {LP5024_OUT20_CLR, 0x00},
>> +    {LP5024_OUT21_CLR, 0x00},
>> +    {LP5024_OUT22_CLR, 0x00},
>> +    {LP5024_OUT23_CLR, 0x00},
>> +    {LP5024_RESET, 0x00}
>> +};
>> +
>> +static const struct regmap_config lp5024_regmap_config = {
>> +    .reg_bits = 8,
>> +    .val_bits = 8,
>> +
>> +    .max_register = LP5024_RESET,
>> +    .reg_defaults = lp5024_reg_defs,
>> +    .num_reg_defaults = ARRAY_SIZE(lp5024_reg_defs),
>> +    .cache_type = REGCACHE_RBTREE,
>> +};
>> +
>> +static int lp5024_set_color_mix(struct lp5024_led *led, u8 color_reg,
>> +                u8 color_val)
>> +{
>> +    return regmap_write(led->priv->regmap, color_reg, color_val);
>> +}
>> +
>> +
>> +static ssize_t ctrl_bank_a_mix_store(struct device *dev,
>> +                struct device_attribute *attr,
>> +                const char *buf, size_t size)
>> +{
>> +    struct led_classdev *led_cdev = dev_get_drvdata(dev);
>> +    struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
>> +                          led_dev);
>> +    u8 mix_value;
>> +    int ret;
>> +
>> +    ret = kstrtou8(buf, 0, &mix_value);
>> +    if (ret)
>> +        return ret;
>> +
>> +    lp5024_set_color_mix(led, LP5024_BNKA_CLR, mix_value);
>> +
>> +    return size;
>> +}
>> +static ssize_t ctrl_bank_b_mix_store(struct device *dev,
>> +                struct device_attribute *attr,
>> +                const char *buf, size_t size)
>> +{
>> +    struct led_classdev *led_cdev = dev_get_drvdata(dev);
>> +    struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
>> +                          led_dev);
>> +    u8 mix_value;
>> +    int ret;
>> +
>> +    ret = kstrtou8(buf, 0, &mix_value);
>> +    if (ret)
>> +        return ret;
>> +
>> +    lp5024_set_color_mix(led, LP5024_BNKB_CLR, mix_value);
>> +
>> +    return size;
>> +}
>> +static ssize_t ctrl_bank_c_mix_store(struct device *dev,
>> +                struct device_attribute *attr,
>> +                const char *buf, size_t size)
>> +{
>> +    struct led_classdev *led_cdev = dev_get_drvdata(dev);
>> +    struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
>> +                          led_dev);
>> +    u8 mix_value;
>> +    int ret;
>> +
>> +    ret = kstrtou8(buf, 0, &mix_value);
>> +    if (ret)
>> +        return ret;
>> +
>> +    lp5024_set_color_mix(led, LP5024_BNKC_CLR, mix_value);
>> +
>> +    return size;
>> +}
>> +
>> +static DEVICE_ATTR_WO(ctrl_bank_a_mix);
>> +static DEVICE_ATTR_WO(ctrl_bank_b_mix);
>> +static DEVICE_ATTR_WO(ctrl_bank_c_mix);
> 
> Why WO?

I did not feel like there was anything to read but I can create the show to read out the register

Of course I am thinking of eliminating these files and combining them with the led_mix files.
And renaming the files to something more generic.
I was thinking of renaming the file to "saturation" and passing in a 32 bit number that will be
parsed as RGB values, well at least the first 24 bytes.

At least this way if the HSV framework comes in then the ABI will be available and only the implemenation
will change.

> 
>> +
>> +static struct attribute *lp5024_ctrl_bank_attrs[] = {
>> +    &dev_attr_ctrl_bank_a_mix.attr,
>> +    &dev_attr_ctrl_bank_b_mix.attr,
>> +    &dev_attr_ctrl_bank_c_mix.attr,
>> +    NULL
>> +};
>> +ATTRIBUTE_GROUPS(lp5024_ctrl_bank);
>> +
>> +static ssize_t led3_mix_store(struct device *dev,
>> +                struct device_attribute *attr,
>> +                const char *buf, size_t size)
>> +{
>> +    struct led_classdev *led_cdev = dev_get_drvdata(dev);
>> +    struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
>> +                          led_dev);
>> +    u8 mix_value;
>> +    u8 reg_value; > +    int ret;
>> +
>> +    ret = kstrtou8(buf, 0, &mix_value);
>> +    if (ret)
>> +        return ret;
>> +
>> +    reg_value = (led->led_number * 3) + LP5024_OUT2_CLR;
> 
> It is more natural if constant goes first. Like BASE_ADDR + offset.

ACK and repeat

> 
>> +
>> +    lp5024_set_color_mix(led, reg_value, mix_value);
>> +
>> +    return size;
>> +}
>> +
>> +static ssize_t led2_mix_store(struct device *dev,
>> +                struct device_attribute *attr,
>> +                const char *buf, size_t size)
>> +{
>> +    struct led_classdev *led_cdev = dev_get_drvdata(dev);
>> +    struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
>> +                          led_dev);
>> +    u8 mix_value;
>> +    u8 reg_value;
>> +    int ret;
>> +
>> +    ret = kstrtou8(buf, 0, &mix_value);
>> +    if (ret)
>> +        return ret;
>> +
>> +    reg_value = (led->led_number * 3) + LP5024_OUT1_CLR;
>> +
>> +    lp5024_set_color_mix(led, reg_value, mix_value);
>> +
>> +    return size;
>> +}
>> +
>> +static ssize_t led1_mix_store(struct device *dev,
>> +                struct device_attribute *attr,
>> +                const char *buf, size_t size)
>> +{
>> +    struct led_classdev *led_cdev = dev_get_drvdata(dev);
>> +    struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
>> +                          led_dev);
>> +    u8 mix_value;
>> +    u8 reg_value;
>> +    int ret;
>> +
>> +    ret = kstrtou8(buf, 0, &mix_value);
>> +    if (ret)
>> +        return ret;
>> +
>> +    reg_value = (led->led_number * 3) + LP5024_OUT0_CLR;
>> +
>> +    lp5024_set_color_mix(led, reg_value, mix_value);
>> +
>> +    return size;
>> +}
>> +
>> +static DEVICE_ATTR_WO(led1_mix);
>> +static DEVICE_ATTR_WO(led2_mix);
>> +static DEVICE_ATTR_WO(led3_mix);
> 
> Why WO?

See above

> 
>> +static struct attribute *lp5024_led_independent_attrs[] = {
>> +    &dev_attr_led1_mix.attr,
>> +    &dev_attr_led2_mix.attr,
>> +    &dev_attr_led3_mix.attr,
>> +    NULL
>> +};
>> +ATTRIBUTE_GROUPS(lp5024_led_independent);
>> +
>> +static int lp5024_brightness_set(struct led_classdev *led_cdev,
>> +                enum led_brightness brt_val)
>> +{
>> +    struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
>> +                          led_dev);
>> +    int ret = 0;
>> +    u8 reg_val;
>> +
>> +    mutex_lock(&led->priv->lock);
>> +
>> +    if (led->ctrl_bank_enabled)
>> +        reg_val = LP5024_BNK_BRT;
>> +    else
>> +        reg_val = led->led_number + LP5024_LED0_BRT;
>> +
>> +    ret = regmap_write(led->priv->regmap, reg_val, brt_val);
>> +
>> +    mutex_unlock(&led->priv->lock);
>> +
>> +    return ret;
>> +}
>> +
>> +static enum led_brightness lp5024_brightness_get(struct led_classdev *led_cdev)
>> +{
>> +    struct lp5024_led *led = container_of(led_cdev, struct lp5024_led,
>> +                          led_dev);
>> +    unsigned int brt_val;
>> +    u8 reg_val;
>> +    int ret;
>> +
>> +    mutex_lock(&led->priv->lock);
>> +
>> +    if (led->ctrl_bank_enabled)
>> +        reg_val = LP5024_BNK_BRT;
>> +    else
>> +        reg_val = led->led_number + LP5024_LED0_BRT;
>> +
>> +    ret = regmap_read(led->priv->regmap, reg_val, &brt_val);
>> +
>> +    mutex_unlock(&led->priv->lock);
>> +
>> +    return brt_val;
>> +}
>> +
>> +static int lp5024_set_led_values(struct lp5024 *priv)
>> +{
>> +    struct lp5024_led *led;
>> +    int i, j;
>> +    u8 led_ctrl_enable = 0;
>> +
>> +    for (i = 0; i <= priv->num_of_leds; i++) {
>> +        led = &priv->leds[i];
>> +        if (led->ctrl_bank_enabled) {
>> +            for (j = 0; j <= LP5024_MAX_LED_STRINGS - 1; j++)
>> +                led_ctrl_enable |= (1 << led->led_strings[j]);
>> +        }
>> +    }
>> +
>> +    regmap_write(priv->regmap, LP5024_LED_CFG0, led_ctrl_enable);
>> +
>> +    return 0;
>> +}
>> +
>> +static int lp5024_init(struct lp5024 *priv)
>> +{
>> +    int ret;
>> +
>> +    if (priv->enable_gpio) {
>> +        gpiod_direction_output(priv->enable_gpio, 1);
>> +    } else {
>> +        ret = regmap_write(priv->regmap, LP5024_RESET, LP5024_SW_RESET);
>> +        if (ret) {
>> +            dev_err(&priv->client->dev,
>> +                "Cannot reset the device\n");
>> +            goto out;
>> +        }
>> +    }
>> +
>> +    ret = lp5024_set_led_values(priv);
>> +    if (ret)
>> +        dev_err(&priv->client->dev, "Setting the CRTL bank failed\n");
>> +
>> +    ret = regmap_write(priv->regmap, LP5024_DEV_CFG0, LP5024_CHIP_EN);
>> +    if (ret) {
>> +        dev_err(&priv->client->dev, "Cannot write ctrl enable\n");
>> +        goto out;
>> +    }
>> +out:
>> +    return ret;
>> +}
>> +
>> +static int lp5024_probe_dt(struct lp5024 *priv)
>> +{
>> +    struct fwnode_handle *child = NULL;
>> +    struct lp5024_led *led;
>> +    const char *name;
>> +    int led_number;
>> +    size_t i = 0;
>> +    int ret;
>> +
>> +    priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
>> +                           "enable", GPIOD_OUT_LOW);
>> +    if (IS_ERR(priv->enable_gpio)) {
>> +        ret = PTR_ERR(priv->enable_gpio);
>> +        dev_err(&priv->client->dev, "Failed to get enable gpio: %d\n",
>> +            ret);
>> +        return ret;
>> +    }
>> +
>> +    priv->regulator = devm_regulator_get(&priv->client->dev, "vled");
>> +    if (IS_ERR(priv->regulator))
>> +        priv->regulator = NULL;
>> +
>> +    if (priv->model_id == LP5018)
>> +        priv->max_leds = LP5018_MAX_LED_STRINGS;
>> +    else
>> +        priv->max_leds = LP5024_MAX_LED_STRINGS;
>> +
>> +    device_for_each_child_node(&priv->client->dev, child) {
>> +        led = &priv->leds[i];
>> +
>> +        if (fwnode_property_present(child, "ti,control-bank"))
>> +            led->ctrl_bank_enabled = 1;
>> +        else
>> +            led->ctrl_bank_enabled = 0;
>> +
>> +        if (led->ctrl_bank_enabled) {
>> +            ret = fwnode_property_read_u32_array(child,
>> +                                 "led-sources",
>> +                                 NULL, 0);
>> +            ret = fwnode_property_read_u32_array(child,
>> +                                 "led-sources",
>> +                                 led->led_strings,
>> +                                 ret);
>> +
>> +            led->led_number = led->led_strings[0];
>> +
>> +        } else {
>> +            ret = fwnode_property_read_u32(child, "led-sources",
>> +                           &led_number);
>> +
>> +            led->led_number = led_number;
>> +        }
>> +        if (ret) {
>> +            dev_err(&priv->client->dev,
>> +                "led-sources property missing\n");
>> +            fwnode_handle_put(child);
>> +            goto child_out;
>> +        }
>> +
>> +        if (led_number > priv->max_leds) {
>> +            dev_err(&priv->client->dev,
>> +                "led-sources property is invalid\n");
>> +            ret = -EINVAL;
>> +            fwnode_handle_put(child);
>> +            goto child_out;
>> +        }
>> +
>> +        ret = fwnode_property_read_string(child, "label", &name);
>> +        if (ret)
>> +            snprintf(led->label, sizeof(led->label),
>> +                "%s::", priv->client->name);
>> +        else
>> +            snprintf(led->label, sizeof(led->label),
>> +                 "%s:%s", priv->client->name, name);
>> +
>> +        fwnode_property_read_string(child, "linux,default-trigger",
>> +                    &led->led_dev.default_trigger);
>> +
>> +        led->priv = priv;
>> +        led->led_dev.name = led->label;
>> +        led->led_dev.max_brightness = 255;
>> +        led->led_dev.brightness_set_blocking = lp5024_brightness_set;
>> +        led->led_dev.brightness_get = lp5024_brightness_get;
>> +
>> +        if (led->ctrl_bank_enabled)
>> +            led->led_dev.groups = lp5024_ctrl_bank_groups;
>> +        else
>> +            led->led_dev.groups = lp5024_led_independent_groups;
>> +
>> +        ret = devm_led_classdev_register(&priv->client->dev,
>> +                         &led->led_dev);
>> +        if (ret) {
>> +            dev_err(&priv->client->dev, "led register err: %d\n",
>> +                ret);
>> +            fwnode_handle_put(child);
>> +            goto child_out;
>> +        }
>> +        i++;
>> +    }
>> +    priv->num_of_leds = i;
>> +
>> +child_out:
>> +    return ret;
>> +}
>> +
>> +static int lp5024_probe(struct i2c_client *client,
>> +            const struct i2c_device_id *id)
>> +{
>> +    struct lp5024 *led;
>> +    int count;
>> +    int ret;
>> +
>> +    count = device_get_child_node_count(&client->dev);
>> +    if (!count) {
>> +        dev_err(&client->dev, "LEDs are not defined in device tree!");
>> +        return -ENODEV;
>> +    }
>> +
>> +    led = devm_kzalloc(&client->dev, struct_size(led, leds, count),
>> +               GFP_KERNEL);
>> +    if (!led)
>> +        return -ENOMEM;
>> +
>> +    mutex_init(&led->lock);
>> +    led->client = client;
>> +    led->dev = &client->dev;
>> +    led->model_id = id->driver_data;
>> +    i2c_set_clientdata(client, led);
>> +
>> +    led->regmap = devm_regmap_init_i2c(client, &lp5024_regmap_config);
>> +    if (IS_ERR(led->regmap)) {
>> +        ret = PTR_ERR(led->regmap);
>> +        dev_err(&client->dev, "Failed to allocate register map: %d\n",
>> +            ret);
>> +        return ret;
>> +    }
>> +
>> +    ret = lp5024_probe_dt(led);
>> +    if (ret)
>> +        return ret;
>> +
>> +    ret = lp5024_init(led);
>> +    if (ret)
>> +        return ret;
>> +
>> +    return 0;
>> +}
>> +
>> +static int lp5024_remove(struct i2c_client *client)
>> +{
>> +    struct lp5024 *led = i2c_get_clientdata(client);
>> +    int ret;
>> +
>> +    ret = regmap_update_bits(led->regmap, LP5024_DEV_CFG0,
>> +                 LP5024_CHIP_EN, 0);
>> +    if (ret) {
>> +        dev_err(&led->client->dev, "Failed to disable regulator\n");
>> +        return ret;
>> +    }
>> +
>> +    if (led->enable_gpio)
>> +        gpiod_direction_output(led->enable_gpio, 0);
>> +
>> +    if (led->regulator) {
>> +        ret = regulator_disable(led->regulator);
>> +        if (ret)
>> +            dev_err(&led->client->dev,
>> +                "Failed to disable regulator\n");
>> +    }
>> +
>> +    mutex_destroy(&led->lock);
>> +
>> +    return 0;
>> +}
>> +
>> +static const struct i2c_device_id lp5024_id[] = {
>> +    { "lp5018", LP5018 },
>> +    { "lp5024", LP5024 },
>> +    { }
>> +};
>> +MODULE_DEVICE_TABLE(i2c, lp5024_id);
>> +
>> +static const struct of_device_id of_lp5024_leds_match[] = {
>> +    { .compatible = "ti,lp5018", },
>> +    { .compatible = "ti,lp5024", },
>> +    {},
>> +};
>> +MODULE_DEVICE_TABLE(of, of_lp5024_leds_match);
>> +
>> +static struct i2c_driver lp5024_driver = {
>> +    .driver = {
>> +        .name    = "lp5024",
>> +        .of_match_table = of_lp5024_leds_match,
>> +    },
>> +    .probe        = lp5024_probe,
>> +    .remove        = lp5024_remove,
>> +    .id_table    = lp5024_id,
>> +};
>> +module_i2c_driver(lp5024_driver);
>> +
>> +MODULE_DESCRIPTION("Texas Instruments LP5024 LED driver");
>> +MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
>> +MODULE_LICENSE("GPL v2");
>>
> 


-- 
------------------
Dan Murphy

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-07 21:14                                               ` Dan Murphy
@ 2019-01-08 21:18                                                 ` Jacek Anaszewski
  2019-01-08 21:25                                                   ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-08 21:18 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

Hi Dan,

On 1/7/19 10:14 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/7/19 2:59 PM, Jacek Anaszewski wrote:
>> Dan,
>>
>> On 1/7/19 8:36 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>>>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>>>> Hi Pavel,
>>>>>
>>>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>>>> Hi!
>>>>>>
>>>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>>>> problems are. It is hard to explain colors over email...
>>>>>>>
>>>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>>>
>>>>>>> I don't see any problems in exposing separate red,green,blue
>>>>>>> files and brightness for the devices with hardware support for
>>>>>>> that.
>>>>>>
>>>>>> Well, that's what we do today, as three separate LEDs, right?
>>>>>
>>>>> No. It doesn't allow for setting color intensity by having
>>>>> the color fixed beforehand. Below is relevant excerpt from
>>>>> the lp5024 documentation. This is not something that can be
>>>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>>>> reservation that the hardware implementation uses PWM
>>>>> for setting color intensity.
>>>>>
>>>>> <quote>
>>>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>>>
>>>>> When color is fixed, the independent intensity-control is used to
>>>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>>>
>>>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>>>
>>>>> Every three consecutive output channels are assigned to their respective
>>>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>>>> device allows 256-step intensity control for each RGB LED module, which
>>>>> helps achieve a smooth dimming effect.
>>>>> </quote>
>>>>>
>>>>>> I don't have problem with that, either; other drivers already do
>>>>>> that. He's free to use existing same interface.
>>>>>>
>>>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>>>> turning led "white".
>>>>>>
>>>>>> So... perhaps we should agree on requirements, first, and then we can
>>>>>> discuss solutions?
>>>>>>
>>>>>> Requirements for RGB LED interface:
>>>>>>
>>>>>> 1) Userspace should be able to set the white color
>>>>>>
>>>>>> 2) Userspace should be able to arbitrary color from well known list
>>>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>>>
>>>>> The difference is that monitor display driver is pre-calibrated
>>>>> for given display by the manufacturer. With the LED controllers the
>>>>> manufacturer has no control over what LEDs will be connected to the
>>>>> iouts. Therefore it should be not surprising that colors produced
>>>>> by custom LEDs are not as user would expect when comparing to
>>>>> the RGB color displayed on the monitor display.
>>>>>
>>>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>>>> that show how to produce various patterns with use of the reference
>>>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>>>
>>>>> Document [0] mentions also specific "Design considerations" in the
>>>>> chapter 2.2:
>>>>>
>>>>> <quote>
>>>>> Several considerations are taken into account for this particular design:
>>>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>>>
>>>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>>>> specific design.
>>>>> </quote>
>>>>>
>>>>> This renders your requirement 2) infeasible with use of custom LEDs
>>>>> any fixed algorithm, since the final effect will always heavily depend
>>>>
>>>> Typo here: s/any fixed/and fixed/
>>>>
>>>>> on the LED circuit design.
>>>>>
>>>>>>
>>>>>>        2a) LEDs probably slightly change color as they age. That's out of
>>>>>>        scope, unless the variation is much greater than on monitors.
>>>>>>
>>>>>>        2b) Manufacturing differences cause small color variation. Again,
>>>>>>        that's out of scope, unless the variation is much greater than on
>>>>>>        monitors.
>>>>>>
>>>>>> Nice to have features:
>>>>>>
>>>>>> 3) Full range of available colors/intensities should be available to
>>>>>> userspace
>>>>>>
>>>>>> 4) Interface should work well with existing triggers
>>>>>>
>>>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>>>> variations).
>>>>>>
>>>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>>>> should be integer or fixed point
>>>>>>
>>>>>> Problems:
>>>>>>
>>>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>>>> red/green/blue channels will result in nothing close to white
>>>>>> light. In fact, to get white light on N900, blue and green channel's
>>>>>> PWM needs to be set pretty low, as in 5%.
>>>>>>
>>>>>> b) LED class does not define any relation between "brightness" in
>>>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>>>> of lumens. RGB color model uses even more complex function.
>>>>>>
>>>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>>>> wavelength of light, while CRTs and LCDs produce broader
>>>>>> spectrums.
>>>>>>
>>>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>>>
>>>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>>>> differences will exist for other colors.
>>>>>>
>>>>>> f) We have existing RGB LEDs represented as three separate
>>>>>> monochromatic LEDs in sysfs.
>>>>>
>>>>> One general question: do you have any solutions in store?
>>>>>
>>>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>>>
>>>>
>>>
>>> I just wanted to point out that there are 4 total devices right now that use the same mapping
>>>
>>> LP5018, LP5024, LP5030 and the LP5036.
>>>
>>> I can implement what ever we would like to I just need to know what to design against.
>>
>> As you can see from the discussion in this thread it may take some
>> time to work out the interface satisfying everyone. I made some design
>> proposal, but Pavel had no warm word for it. It would be easier if
>> we had more opinions.
> 
> I got it from the threads and just the time invested in the FW and HSV.
> 
>>
>> How do you feel about using brightness file for setting LEDn_BRIGHTNESS?
> 
> I am using that now.  The brightness file will adjust the overall brightness of the LED group
> or bank pending on how the LEDs are grouped in the DT file.
> 
>>
>> Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
>> increasing color lightness (i.e. the pattern presented in the video [0]
>> starting from 1:22)?
> 
> No unfortunately this is why I introduced the new files to control the individual RGB intensities
> so that the designers can set, tune, create color variations or patterns like the video.
> 
> The RGB group brightness would be independent based on lighting conditions, enclosures and diffusers.
> So you could technically be changing color and overall brightness virtually simultaneously

Oh, so this is surprising. Now it gets even more obscure to me.

It would be really helpful if we could see a video showing
the LED effects with regard to the applied settings.

>>> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.
>>
>> Do what you deem most suitable for you. We are here only to help
>> merging the patches, but keeping in mind that kernel interface once
>> introduced must be preserved forever. Therefore we need to do our
>> best to make the best possible design decisions.
>>
>> [0] https://www.youtube.com/watch?v=qdt-alh8i6E
>>
> 
> I understand.  Maybe I can make the files generic to use for either control or individual control.
> 
> We can probably define new ABI's until either HSV or DT frameworks get going.  And them make the file presentation
> configurable and default to the new files.

I am leaning towards it. Just commented on your patches.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-08 21:16       ` Jacek Anaszewski
@ 2019-01-08 21:22         ` Dan Murphy
  2019-01-09 20:12           ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-08 21:22 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
> On 1/8/19 9:53 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>> Dan,
>>>
>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>> or as part of a control bank group.  These devices have the ability
>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>> independent of the overall brightness of the LED grouping.
>>>>
>>>> Datasheet:
>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>
>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>> ---
>>>>    .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>    1 file changed, 63 insertions(+)
>>>>    create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>> new file mode 100644
>>>> index 000000000000..9567aa6f7813
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>> @@ -0,0 +1,63 @@
>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>> +
>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>> +white-LED driver designed for LCD display backlighting.
>>>> +
>>>> +The main difference between the LP5024 and L5018 is the number of
>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>> +LP5018 supports eighteen strings.
>>>> +
>>>> +Required properties:
>>>> +    - compatible:
>>>> +        "ti,lp5018"
>>>> +        "ti,lp5024"
>>>> +    - reg :  I2C slave address
>>>> +    - #address-cells : 1
>>>> +    - #size-cells : 0
>>>> +
>>>> +Optional properties:
>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>> +    - vled-supply : LED supply
>>>> +
>>>> +Required child properties:
>>>> +    - reg : Is the child node iteration.
>>>> +    - led-sources : LP5024 - 0 - 7
>>>> +            LP5018 - 0 - 5
>>>> +            Declares the LED string or strings that the child node
>>>> +            will control.  If ti,control-bank is set then this
>>>> +            property will contain multiple LED IDs.
>>>> +
>>>> +Optional child properties:
>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>> +    - linux,default-trigger :
>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>> +                led-sources property are grouped within a control
>>>> +                bank for brightness and mixing control.
>>>> +
>>>> +Example:
>>>> +
>>>> +led-controller@28 {
>>>> +    compatible = "ti,lp5024";
>>>> +    reg = <0x28>;
>>>> +    #address-cells = <1>;
>>>> +    #size-cells = <0>;
>>>> +
>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>> +    vled-supply = <&vbatt>;
>>>> +
>>>> +    led@0 {
>>>> +        reg = <0>;
>>>> +        led-sources = <1>;
>>>> +    };
>>>> +
>>>> +    led@1 {
>>>> +        reg = <1>;
>>>> +        led-sources = <0 6>;
>>>> +        ti,control-bank;
>>>
>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>> greater than 1 mean that the node describes control bank?
>>>
>>
>> That will work too.
> 
>>> Also, does it make sense to have only two LEDs in the bank?
>>
>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>> See the description above of the led-sources
> 
> OK, I confused RGB LED modules with banks.
> 
> Shouldn't we allow for defining either strings or RGB LED
> triplets somehow then?
> 

Well that is what this should be doing.  If you define a single LED in LED sources then
the triplet is controlled via the associated LEDx_brightness register.

If you have multiple LED sources defined in the led-sources then those LEDs would be grouped in the bank.
I guess I need to provide some protection or a warning if a DT defines two banks because there is only one bank control.

Dan

-- 
------------------
Dan Murphy

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-08 21:18                                                 ` Jacek Anaszewski
@ 2019-01-08 21:25                                                   ` Dan Murphy
  2019-01-10 12:46                                                     ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-08 21:25 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

Jacek

On 1/8/19 3:18 PM, Jacek Anaszewski wrote:
> Hi Dan,
> 
> On 1/7/19 10:14 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/7/19 2:59 PM, Jacek Anaszewski wrote:
>>> Dan,
>>>
>>> On 1/7/19 8:36 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>>>>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>>>>> Hi Pavel,
>>>>>>
>>>>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>>>>> Hi!
>>>>>>>
>>>>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>>>>> problems are. It is hard to explain colors over email...
>>>>>>>>
>>>>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>>>>
>>>>>>>> I don't see any problems in exposing separate red,green,blue
>>>>>>>> files and brightness for the devices with hardware support for
>>>>>>>> that.
>>>>>>>
>>>>>>> Well, that's what we do today, as three separate LEDs, right?
>>>>>>
>>>>>> No. It doesn't allow for setting color intensity by having
>>>>>> the color fixed beforehand. Below is relevant excerpt from
>>>>>> the lp5024 documentation. This is not something that can be
>>>>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>>>>> reservation that the hardware implementation uses PWM
>>>>>> for setting color intensity.
>>>>>>
>>>>>> <quote>
>>>>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>>>>
>>>>>> When color is fixed, the independent intensity-control is used to
>>>>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>>>>
>>>>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>>>>
>>>>>> Every three consecutive output channels are assigned to their respective
>>>>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>>>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>>>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>>>>> device allows 256-step intensity control for each RGB LED module, which
>>>>>> helps achieve a smooth dimming effect.
>>>>>> </quote>
>>>>>>
>>>>>>> I don't have problem with that, either; other drivers already do
>>>>>>> that. He's free to use existing same interface.
>>>>>>>
>>>>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>>>>> turning led "white".
>>>>>>>
>>>>>>> So... perhaps we should agree on requirements, first, and then we can
>>>>>>> discuss solutions?
>>>>>>>
>>>>>>> Requirements for RGB LED interface:
>>>>>>>
>>>>>>> 1) Userspace should be able to set the white color
>>>>>>>
>>>>>>> 2) Userspace should be able to arbitrary color from well known list
>>>>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>>>>
>>>>>> The difference is that monitor display driver is pre-calibrated
>>>>>> for given display by the manufacturer. With the LED controllers the
>>>>>> manufacturer has no control over what LEDs will be connected to the
>>>>>> iouts. Therefore it should be not surprising that colors produced
>>>>>> by custom LEDs are not as user would expect when comparing to
>>>>>> the RGB color displayed on the monitor display.
>>>>>>
>>>>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>>>>> that show how to produce various patterns with use of the reference
>>>>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>>>>
>>>>>> Document [0] mentions also specific "Design considerations" in the
>>>>>> chapter 2.2:
>>>>>>
>>>>>> <quote>
>>>>>> Several considerations are taken into account for this particular design:
>>>>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>>>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>>>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>>>>
>>>>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>>>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>>>>> specific design.
>>>>>> </quote>
>>>>>>
>>>>>> This renders your requirement 2) infeasible with use of custom LEDs
>>>>>> any fixed algorithm, since the final effect will always heavily depend
>>>>>
>>>>> Typo here: s/any fixed/and fixed/
>>>>>
>>>>>> on the LED circuit design.
>>>>>>
>>>>>>>
>>>>>>>        2a) LEDs probably slightly change color as they age. That's out of
>>>>>>>        scope, unless the variation is much greater than on monitors.
>>>>>>>
>>>>>>>        2b) Manufacturing differences cause small color variation. Again,
>>>>>>>        that's out of scope, unless the variation is much greater than on
>>>>>>>        monitors.
>>>>>>>
>>>>>>> Nice to have features:
>>>>>>>
>>>>>>> 3) Full range of available colors/intensities should be available to
>>>>>>> userspace
>>>>>>>
>>>>>>> 4) Interface should work well with existing triggers
>>>>>>>
>>>>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>>>>> variations).
>>>>>>>
>>>>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>>>>> should be integer or fixed point
>>>>>>>
>>>>>>> Problems:
>>>>>>>
>>>>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>>>>> red/green/blue channels will result in nothing close to white
>>>>>>> light. In fact, to get white light on N900, blue and green channel's
>>>>>>> PWM needs to be set pretty low, as in 5%.
>>>>>>>
>>>>>>> b) LED class does not define any relation between "brightness" in
>>>>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>>>>> of lumens. RGB color model uses even more complex function.
>>>>>>>
>>>>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>>>>> wavelength of light, while CRTs and LCDs produce broader
>>>>>>> spectrums.
>>>>>>>
>>>>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>>>>
>>>>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>>>>> differences will exist for other colors.
>>>>>>>
>>>>>>> f) We have existing RGB LEDs represented as three separate
>>>>>>> monochromatic LEDs in sysfs.
>>>>>>
>>>>>> One general question: do you have any solutions in store?
>>>>>>
>>>>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>>>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>>>>
>>>>>
>>>>
>>>> I just wanted to point out that there are 4 total devices right now that use the same mapping
>>>>
>>>> LP5018, LP5024, LP5030 and the LP5036.
>>>>
>>>> I can implement what ever we would like to I just need to know what to design against.
>>>
>>> As you can see from the discussion in this thread it may take some
>>> time to work out the interface satisfying everyone. I made some design
>>> proposal, but Pavel had no warm word for it. It would be easier if
>>> we had more opinions.
>>
>> I got it from the threads and just the time invested in the FW and HSV.
>>
>>>
>>> How do you feel about using brightness file for setting LEDn_BRIGHTNESS?
>>
>> I am using that now.  The brightness file will adjust the overall brightness of the LED group
>> or bank pending on how the LEDs are grouped in the DT file.
>>
>>>
>>> Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
>>> increasing color lightness (i.e. the pattern presented in the video [0]
>>> starting from 1:22)?
>>
>> No unfortunately this is why I introduced the new files to control the individual RGB intensities
>> so that the designers can set, tune, create color variations or patterns like the video.
>>
>> The RGB group brightness would be independent based on lighting conditions, enclosures and diffusers.
>> So you could technically be changing color and overall brightness virtually simultaneously
> 
> Oh, so this is surprising. Now it gets even more obscure to me.
> 
> It would be really helpful if we could see a video showing
> the LED effects with regard to the applied settings.

Well I am doing a test off the command line to ensure the user space can interface with the RGB LED.

I can ping someone in product development to see the application of this device if that would help.
We did give them a test driver to work on their features but told them the driver is not final until it
is in the mainline kernel

Dan

> 
>>>> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.
>>>
>>> Do what you deem most suitable for you. We are here only to help
>>> merging the patches, but keeping in mind that kernel interface once
>>> introduced must be preserved forever. Therefore we need to do our
>>> best to make the best possible design decisions.
>>>
>>> [0] https://www.youtube.com/watch?v=qdt-alh8i6E
>>>
>>
>> I understand.  Maybe I can make the files generic to use for either control or individual control.
>>
>> We can probably define new ABI's until either HSV or DT frameworks get going.  And them make the file presentation
>> configurable and default to the new files.
> 
> I am leaning towards it. Just commented on your patches.
> 


-- 
------------------
Dan Murphy

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-06 15:52                                       ` Jacek Anaszewski
  2019-01-07 19:13                                         ` Jacek Anaszewski
@ 2019-01-08 22:59                                         ` Pavel Machek
  2019-01-09  7:11                                           ` Vesa Jääskeläinen
  1 sibling, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2019-01-08 22:59 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Vesa Jääskeläinen, Dan Murphy, robh+dt,
	devicetree, linux-kernel, linux-leds

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

Hi!

> >>>Grab yourself an RGB LED and play with it; you'll see what the
> >>>problems are. It is hard to explain colors over email...
> >>
> >>Video [0] gives some overview of lp5024 capabilities.
> >>
> >>I don't see any problems in exposing separate red,green,blue
> >>files and brightness for the devices with hardware support for
> >>that.
> >
> >Well, that's what we do today, as three separate LEDs, right?
> 
> No. It doesn't allow for setting color intensity by having
> the color fixed beforehand. Below is relevant excerpt from
> the lp5024 documentation. This is not something that can be
> mapped to RGB color space, but rather to HSV/HSL, with the
> reservation that the hardware implementation uses PWM
> for setting color intensity.

So they have feature where they have independent controls for each
channel, then one common control per three channels. Other chips have
common control for all the LEDs, for example. We don't support that
currently; lets focus on the RGB thing first.

> >I don't have problem with that, either; other drivers already do
> >that. He's free to use existing same interface.
> >
> >But that is insufficient, as it does not allow simple stuff, such as
> >turning led "white".
> >
> >So... perhaps we should agree on requirements, first, and then we can
> >discuss solutions?
> >
> >Requirements for RGB LED interface:
> >
> >1) Userspace should be able to set the white color
> >
> >2) Userspace should be able to arbitrary color from well known list
> >and it should approximately match what would CRT, LCD or OLED monitor display
> 
> The difference is that monitor display driver is pre-calibrated
> for given display by the manufacturer. With the LED controllers the
> manufacturer has no control over what LEDs will be connected to the
> iouts. Therefore it should be not surprising that colors produced
> by custom LEDs are not as user would expect when comparing to
> the RGB color displayed on the monitor display.

It is true that _chip_ manufacturer can not know what LEDs will be
connected. But _system_ manufacturer can and should know that, and
should tell be able to tell us in the dts.

> This renders your requirement 2) infeasible with use of custom LEDs
> any fixed algorithm, since the final effect will always heavily depend
> on the LED circuit design.

Depending on LED circuit design and actual LEDs connected is okay.. we
just need to get information from _system_ designer (not chip
designer), and pass it to a place where color is computed.

> >a) RGB LEDs are usually not balanced. Setting 100% PWM on
> >red/green/blue channels will result in nothing close to white
> >light. In fact, to get white light on N900, blue and green channel's
> >PWM needs to be set pretty low, as in 5%.
> >
> >b) LED class does not define any relation between "brightness" in
> >sysfs and ammount of light in lumens. Some drivers use close to linear
> >relation, some use exponential relation. Human eyes percieve logarithm
> >of lumens. RGB color model uses even more complex function.
> 
> One general question: do you have any solutions in store?

I played with LEDs on N900 over the weekend, yes.

And getting reasonable colors seems to be possible, when a) and b) are
solved... a) seems to be more important than b).

Now... this does not tell us how we should design kernel<->user
interface, but it should tell us that main goals - 1) and 2) are
possible.

Best regards,

									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] 106+ messages in thread

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-07 19:34                               ` Dan Murphy
@ 2019-01-09  6:20                                 ` Vesa Jääskeläinen
  0 siblings, 0 replies; 106+ messages in thread
From: Vesa Jääskeläinen @ 2019-01-09  6:20 UTC (permalink / raw)
  To: Dan Murphy, Jacek Anaszewski, Pavel Machek
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Hi Dan,

On 07/01/2019 21.34, Dan Murphy wrote:
> Vesa
> 
> On 1/4/19 6:39 PM, Vesa Jääskeläinen wrote:
>> Hi Jacek,
>>
>> On 04/01/2019 23.37, Jacek Anaszewski wrote:
>>> But, aside from that hypothetic issue, we need a solution for
>>> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
>>> via a single register write. How would you propose to address that?
>>
>> You could model it to something like this in device tree:
>>
>> led-module @ <i2c-address> {
>>      compatible = "lp5024";
>>
>>      // There is in hardware setup to use either linear or
>>      // logarithmic scaling:
>>      //enable-logarithmic-brightness;
>>
>>      led0 {
>>          // this will create led instance for LED0 in lp5024
>>          label = "lp-led0";
>>         
>>          // This specifies LED number within lp5024
>>          led-index = <0>;   // set output-base as 0*3 == 0
>>         
>>          element-red {
>>              // refers to OUT0
>>              output-offset = <0>;
>>          };
>>         
>>          element-green {
>>              // refers to OUT1
>>              output-offset = <1>;
>>          };
>>         
>>          element-blue {
>>              // refers to OUT2
>>              output-offset = <2>;
>>          };
>>         
>>      };
>>
>>      led1 {
>>          // this will create led instance for LED1 in lp5024
>>          label = "lp-led1";
>>         
>>          // This specifies LED number within lp5024
>>          led-index = <1>;   // set output-base as 1*3 == 3
>>
> 
> Can we not use led-sources like I have done already?

It was just for illustration of the idea. Names can be agreed. I have 
nothing against led-sources name. I was just looking at datasheet to try 
to undestand what it did and then tried to figure out if it could be 
mapped the idea I have been playing with.

> I really like to keep the DT nodes simple and re-use nodes that exist if possible.

I'll reply to Jacek's email about more clarifications of the idea.

Thanks,
Vesa Jääskeläinen

> My code already maps and groups the outputs into the associated banks

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-07 21:13                               ` Jacek Anaszewski
  2019-01-07 21:15                                 ` Dan Murphy
@ 2019-01-09  6:46                                 ` Vesa Jääskeläinen
  2019-01-13 16:36                                   ` Jacek Anaszewski
  1 sibling, 1 reply; 106+ messages in thread
From: Vesa Jääskeläinen @ 2019-01-09  6:46 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

Hi Jacek,

On 07/01/2019 23.13, Jacek Anaszewski wrote:
> Hi Vesa,
> 
> On 1/5/19 1:39 AM, Vesa Jääskeläinen wrote:
>> Hi Jacek,
>>
>> On 04/01/2019 23.37, Jacek Anaszewski wrote:
>>> But, aside from that hypothetic issue, we need a solution for
>>> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
>>> via a single register write. How would you propose to address that?
>>
>> You could model it to something like this in device tree:
>>
>> led-module @ <i2c-address> {
>>      compatible = "lp5024";
>>
>>      // There is in hardware setup to use either linear or
>>      // logarithmic scaling:
>>      //enable-logarithmic-brightness;
>>
>>      led0 {
>>          // this will create led instance for LED0 in lp5024
>>          label = "lp-led0";
>>
>>          // This specifies LED number within lp5024
>>          led-index = <0>;   // set output-base as 0*3 == 0
>>
>>          element-red {
>>              // refers to OUT0
>>              output-offset = <0>;
>>          };
>>
>>          element-green {
>>              // refers to OUT1
>>              output-offset = <1>;
>>          };
>>
>>          element-blue {
>>              // refers to OUT2
>>              output-offset = <2>;
>>          };
>>
>>      };
>>
>>      led1 {
>>          // this will create led instance for LED1 in lp5024
>>          label = "lp-led1";
>>
>>          // This specifies LED number within lp5024
>>          led-index = <1>;   // set output-base as 1*3 == 3
>>
>>          element-red {
>>              // refers to OUT3
>>              output-offset = <0>;
>>          };
>>
>>          element-green {
>>              // refers to OUT4
>>              output-offset = <1>;
>>          };
>>
>>          element-blue {
>>              // refers to OUT5
>>              output-offset = <2>;
>>          };
>>
>>      };
>>
>>      bank-led {
>>          // this will create led instance for bank leds in lp5024
>>          label = "lp-bank-led";
>>
>>          // configured bank led configuration
>>          led-index = <2 3 4 5 6 7>;
>>          // As here is list of led-indices this entry is
>>          // assumed to be bank configuration. Bank mode is enable
>>          // for the indices.
>>
>>          // set output-base as BANK A
>>
>>          element-red {
>>              // refers to BANK A
>>              output-offset = <0>;
>>          };
>>
>>          element-green {
>>              // refers to BANK B
>>              output-offset = <1>;
>>          };
>>
>>          element-blue {
>>              // refers to BANK C
>>              output-offset = <2>;
>>          };
>>      };
>> };
>>
>> This would then create three led instances and each led instance has 
>> brightness setting and that goes straight to hardware.
>>
>> If one would want to override hardware control for brightness then I 
>> suppose you would define in led node something like:
>>
>>      brightness-model = "hsl"
>>
>> This would then pick red, green and blue elements for hsl calculations 
>> and others color elements for linear. LED specific hardware brightness 
>> would then be either 0 or 0xFF depending if all of LED color elements 
>> are zero or not.
>>
>> Would that kind of model work?
> 
> I'd prefer to have single RGB LED device. And your DT design
> is unnecessarily complex and a bit confusing.

As this chip series is kinda designed for N x RGB LED's my idea was that 
if from user space point of view we model it as N times of individual 
RGB LED instances that may not even have anything to do with together. 
Eg. could be used for different purposes and such.

And in device tree one would define logical connections for the leds so 
they would be mapped logically correct to user space.

If one would define it like:

led1 {
	// this will create led instance for LED1 in lp5024
	label = "lp-led1";
	
	// This specifies LED number within lp5024
	led-sources = <1>;
};
(note changed led-index to led-sources as that is what Pavel had and 
preferred)

We could assume that it is RGB led in this driver's case and create it 
automatically with elements "red", "green", and "blue". And this could 
then be mapped automatically to HSL color elements or what ever the 
model would be.

If you would model it differently in your hardware design then you would 
need to define more device tree nodes. Eg. if your order of LEDs would 
not be red, green, blue. Or if you would have non-RGB led(s) in there.

> Also, you provided scarce information about sysfs interface.
> It would be nice to see the sequence of commands.

In this case it could be:

# Note: Updated color to value array model.

$ ls /sys/class/leds
lp-led0	lp-led1	lp-bank-led

$ ls /sys/class/leds/lp-led0
brightness	color

$ ls /sys/class/leds/lp-led1
brightness	color

$ ls /sys/class/leds/lp-bank-led
brightness	color

# Idea of above is that as brightness is for triplet:
#   OUT(LED*3 + 0), OUT(LED*3 + 1), OUT(LED*3 + 2),
# Then if we model it like RGB LED then brightness would automatically
# map to correct OUTputs and be grouped from user space point of view
# logically in correct place.

# set first led to red
echo "255 0 0" > /sys/class/leds/lp-led0/color

# set second led to green
echo "0 255 0" > /sys/class/leds/lp-led1/color

# set bank led to blue
echo "0 0 255" > /sys/class/leds/lp-bank-led/color

# Set hardware brightness control to middle
echo "128" > /sys/class/leds/lp-bank-led/brightness

# If we would have software controlled virtual brightness enabled for
# particular led classdev then there would be some math in either user
# or in kernel space.

Thanks,
Vesa Jääskeläinen

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-08 22:59                                         ` Pavel Machek
@ 2019-01-09  7:11                                           ` Vesa Jääskeläinen
  2019-01-13 16:37                                             ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Vesa Jääskeläinen @ 2019-01-09  7:11 UTC (permalink / raw)
  To: Pavel Machek, Jacek Anaszewski
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

Hi Pavel,

On 09/01/2019 0.59, Pavel Machek wrote:
> Hi!
> 
>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>> problems are. It is hard to explain colors over email...
>>>>
>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>
>>>> I don't see any problems in exposing separate red,green,blue
>>>> files and brightness for the devices with hardware support for
>>>> that.
>>>
>>> Well, that's what we do today, as three separate LEDs, right?
>>
>> No. It doesn't allow for setting color intensity by having
>> the color fixed beforehand. Below is relevant excerpt from
>> the lp5024 documentation. This is not something that can be
>> mapped to RGB color space, but rather to HSV/HSL, with the
>> reservation that the hardware implementation uses PWM
>> for setting color intensity.
> 
> So they have feature where they have independent controls for each
> channel, then one common control per three channels. Other chips have
> common control for all the LEDs, for example. We don't support that
> currently; lets focus on the RGB thing first.
> 
>>> I don't have problem with that, either; other drivers already do
>>> that. He's free to use existing same interface.
>>>
>>> But that is insufficient, as it does not allow simple stuff, such as
>>> turning led "white".
>>>
>>> So... perhaps we should agree on requirements, first, and then we can
>>> discuss solutions?
>>>
>>> Requirements for RGB LED interface:
>>>
>>> 1) Userspace should be able to set the white color
>>>
>>> 2) Userspace should be able to arbitrary color from well known list
>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>
>> The difference is that monitor display driver is pre-calibrated
>> for given display by the manufacturer. With the LED controllers the
>> manufacturer has no control over what LEDs will be connected to the
>> iouts. Therefore it should be not surprising that colors produced
>> by custom LEDs are not as user would expect when comparing to
>> the RGB color displayed on the monitor display.
> 
> It is true that _chip_ manufacturer can not know what LEDs will be
> connected. But _system_ manufacturer can and should know that, and
> should tell be able to tell us in the dts.
> 
>> This renders your requirement 2) infeasible with use of custom LEDs
>> any fixed algorithm, since the final effect will always heavily depend
>> on the LED circuit design.
> 
> Depending on LED circuit design and actual LEDs connected is okay.. we
> just need to get information from _system_ designer (not chip
> designer), and pass it to a place where color is computed.
> 
>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>> red/green/blue channels will result in nothing close to white
>>> light. In fact, to get white light on N900, blue and green channel's
>>> PWM needs to be set pretty low, as in 5%.
>>>
>>> b) LED class does not define any relation between "brightness" in
>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>> relation, some use exponential relation. Human eyes percieve logarithm
>>> of lumens. RGB color model uses even more complex function.
>>
>> One general question: do you have any solutions in store?
> 
> I played with LEDs on N900 over the weekend, yes.
> 
> And getting reasonable colors seems to be possible, when a) and b) are
> solved... a) seems to be more important than b).
> 
> Now... this does not tell us how we should design kernel<->user
> interface, but it should tell us that main goals - 1) and 2) are
> possible.

I was thinking about this calibration and color correctness thing and I 
am thinking a bit that it should be partly in kernel and partly in user 
space.

For displays and printers there are defined icc-profiles that define how 
colors are mapped to particular device in cases when you want to have 
accurate color representation. In theory to get accurate LED output one 
could model LEDs with icc profile and then pick your color and convert 
it with icc profile to actual raw hardware values. Then this raw 
hardware value could be written from user space to kernel.

In kernel we could provide raw hardware value support and in case of PWM 
IC controlled LEDs we could provide curve mapping to linearize the 
behavior of values entered to enable use in cases where close enough is 
good enough.

Eg. if you want to have "white" then you have your color space picker 
like sRGB(255,255,255). Then you would define icc profile it might 
translate to hardware raw values 253%, 230%, 225%.

Then you would write this to kernel with:

# set red, green and blue color elements
echo "253 230 225" > color

In this case however behavior of brightness node is challening in 
accuracy domain. Britghtness value 255 would of course provide 1:1 
mapping in this case.

To go right to correct color and brightness at one go we could have 
optional brightness at the end of color value array:

# set red, green and blue color element and brightness setting:
echo "253 230 225 255" > color

If you want to have fancier behavior for brightness in your system then 
we probably need to have configurable brightness model.

- hardware, like in lp5024 case would map to hardware register (would be 
omitted if there is no such register)
- onoff, would act like light switch ON/OFF eg. either configured value 
or all zeroes.
- scaled, would multiply the color elements
- hsl, would use hsl formula
- and this can be extended later with some other models and allows us to 
start with with some models now.

We could define this in devicetree and from sysfs a bit like with trigger:

$ cat brightness_model
[hardware] onoff scaled hsl

$ echo "hsl" > brightness_model

$ cat brightness_model
hardware onoff scaled [hsl]

Then we could have "color_names" or such sysfs entry to determine allow 
user space auto detection of led elements):

$ cat color_names
red green blue

I suppose this model would provide flexibilty for multiple cases. Make 
it simple for most uses, allow accuracy with icc profiles for advanced 
users, would allow atomic color setting.

I have updated (not yet in github) my tests to use color array model and 
color_names already and can play with brightness_model thing if this is 
something that is good path?

What do you think?

Thanks,
Vesa Jääskeläinen

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-08 21:22         ` Dan Murphy
@ 2019-01-09 20:12           ` Jacek Anaszewski
  2019-01-09 21:12             ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-09 20:12 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Hi Dan,

On 1/8/19 10:22 PM, Dan Murphy wrote:
> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>> Dan,
>>>>
>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>> or as part of a control bank group.  These devices have the ability
>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>> independent of the overall brightness of the LED grouping.
>>>>>
>>>>> Datasheet:
>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>
>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>> ---
>>>>>     .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>     1 file changed, 63 insertions(+)
>>>>>     create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>> new file mode 100644
>>>>> index 000000000000..9567aa6f7813
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>> @@ -0,0 +1,63 @@
>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>> +
>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>> +white-LED driver designed for LCD display backlighting.
>>>>> +
>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>> +LP5018 supports eighteen strings.
>>>>> +
>>>>> +Required properties:
>>>>> +    - compatible:
>>>>> +        "ti,lp5018"
>>>>> +        "ti,lp5024"
>>>>> +    - reg :  I2C slave address
>>>>> +    - #address-cells : 1
>>>>> +    - #size-cells : 0
>>>>> +
>>>>> +Optional properties:
>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>> +    - vled-supply : LED supply
>>>>> +
>>>>> +Required child properties:
>>>>> +    - reg : Is the child node iteration.
>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>> +            LP5018 - 0 - 5
>>>>> +            Declares the LED string or strings that the child node
>>>>> +            will control.  If ti,control-bank is set then this
>>>>> +            property will contain multiple LED IDs.
>>>>> +
>>>>> +Optional child properties:
>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>> +    - linux,default-trigger :
>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>> +                led-sources property are grouped within a control
>>>>> +                bank for brightness and mixing control.
>>>>> +
>>>>> +Example:
>>>>> +
>>>>> +led-controller@28 {
>>>>> +    compatible = "ti,lp5024";
>>>>> +    reg = <0x28>;
>>>>> +    #address-cells = <1>;
>>>>> +    #size-cells = <0>;
>>>>> +
>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>> +    vled-supply = <&vbatt>;
>>>>> +
>>>>> +    led@0 {
>>>>> +        reg = <0>;
>>>>> +        led-sources = <1>;
>>>>> +    };
>>>>> +
>>>>> +    led@1 {
>>>>> +        reg = <1>;
>>>>> +        led-sources = <0 6>;
>>>>> +        ti,control-bank;
>>>>
>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>> greater than 1 mean that the node describes control bank?
>>>>
>>>
>>> That will work too.
>>
>>>> Also, does it make sense to have only two LEDs in the bank?
>>>
>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>> See the description above of the led-sources
>>
>> OK, I confused RGB LED modules with banks.
>>
>> Shouldn't we allow for defining either strings or RGB LED
>> triplets somehow then?
>>
> 
> Well that is what this should be doing.  If you define a single LED in LED sources then
> the triplet is controlled via the associated LEDx_brightness register.

led-sources should map to iouts directly.
So, for RGB LED modules I would expect:

LED0: led-sources = <0 1 2>;
LED1: led-sources = <3 4 5>;
LED2: led-sources = <6 7 8>;
and so on.

for banks:

Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
Bank B with iouts 2,4,10:  led-sources<2 4 10>;
Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;

We could additionally mark banks with ti,control-bank,
but I'm not sure if it would ease parsing, since
you will have to validate iouts configuration anyway.

> If you have multiple LED sources defined in the led-sources then those LEDs would be grouped in the bank.
> I guess I need to provide some protection or a warning if a DT defines two banks because there is only one bank control.

Does the hardware allow the IOUT to belong to an RGB LED module
and to a bank in the same time?

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-09 20:12           ` Jacek Anaszewski
@ 2019-01-09 21:12             ` Dan Murphy
  2019-01-09 21:28               ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-09 21:12 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
> Hi Dan,
> 
> On 1/8/19 10:22 PM, Dan Murphy wrote:
>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>> Dan,
>>>>>
>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>
>>>>>> Datasheet:
>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>
>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>> ---
>>>>>>     .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>     1 file changed, 63 insertions(+)
>>>>>>     create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>> new file mode 100644
>>>>>> index 000000000000..9567aa6f7813
>>>>>> --- /dev/null
>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>> @@ -0,0 +1,63 @@
>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>> +
>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>> +
>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>> +LP5018 supports eighteen strings.
>>>>>> +
>>>>>> +Required properties:
>>>>>> +    - compatible:
>>>>>> +        "ti,lp5018"
>>>>>> +        "ti,lp5024"
>>>>>> +    - reg :  I2C slave address
>>>>>> +    - #address-cells : 1
>>>>>> +    - #size-cells : 0
>>>>>> +
>>>>>> +Optional properties:
>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>> +    - vled-supply : LED supply
>>>>>> +
>>>>>> +Required child properties:
>>>>>> +    - reg : Is the child node iteration.
>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>> +            LP5018 - 0 - 5
>>>>>> +            Declares the LED string or strings that the child node
>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>> +            property will contain multiple LED IDs.
>>>>>> +
>>>>>> +Optional child properties:
>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>> +    - linux,default-trigger :
>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>> +                led-sources property are grouped within a control
>>>>>> +                bank for brightness and mixing control.
>>>>>> +
>>>>>> +Example:
>>>>>> +
>>>>>> +led-controller@28 {
>>>>>> +    compatible = "ti,lp5024";
>>>>>> +    reg = <0x28>;
>>>>>> +    #address-cells = <1>;
>>>>>> +    #size-cells = <0>;
>>>>>> +
>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>> +    vled-supply = <&vbatt>;
>>>>>> +
>>>>>> +    led@0 {
>>>>>> +        reg = <0>;
>>>>>> +        led-sources = <1>;
>>>>>> +    };
>>>>>> +
>>>>>> +    led@1 {
>>>>>> +        reg = <1>;
>>>>>> +        led-sources = <0 6>;
>>>>>> +        ti,control-bank;
>>>>>
>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>> greater than 1 mean that the node describes control bank?
>>>>>
>>>>
>>>> That will work too.
>>>
>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>
>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>> See the description above of the led-sources
>>>
>>> OK, I confused RGB LED modules with banks.
>>>
>>> Shouldn't we allow for defining either strings or RGB LED
>>> triplets somehow then?
>>>
>>
>> Well that is what this should be doing.  If you define a single LED in LED sources then
>> the triplet is controlled via the associated LEDx_brightness register.
> 
> led-sources should map to iouts directly.
> So, for RGB LED modules I would expect:
> 
> LED0: led-sources = <0 1 2>;
> LED1: led-sources = <3 4 5>;
> LED2: led-sources = <6 7 8>;
> and so on.

> 
> for banks:
> 
> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
> 

Ok the led-sources would need to be different then this as I don't define the sources for banks.

The led-sources for the banks and the individual groups will have different meanings within the same
document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
it would be controlled by the bank brightness register.

Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
registers.

> We could additionally mark banks with ti,control-bank,

We would have to keep the ti,control-bank node based on the above.

> but I'm not sure if it would ease parsing, since
> you will have to validate iouts configuration anyway.
> 
>> If you have multiple LED sources defined in the led-sources then those LEDs would be grouped in the bank.
>> I guess I need to provide some protection or a warning if a DT defines two banks because there is only one bank control.
> 
> Does the hardware allow the IOUT to belong to an RGB LED module
> and to a bank in the same time?
> 

No it does not.  LED_CONFIG0 sets the bit if it is control bank or not.

Section 8.3.2 in the data sheet says
"When a channel is configured in
LED bank-control mode, the related color mixing and intensity control is governed by the bank control registers
(BANK_A_COLOR, BANK_B_COLOR, BANK_C_COLOR, and BANK_BRIGHTNESS) regardless of the inputs
on its own color-mixing and intensity-control registers."

-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-09 21:12             ` Dan Murphy
@ 2019-01-09 21:28               ` Jacek Anaszewski
  2019-01-09 21:31                 ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-09 21:28 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

On 1/9/19 10:12 PM, Dan Murphy wrote:
> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>> Hi Dan,
>>
>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>> Jacek
>>>>>
>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>> Dan,
>>>>>>
>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>
>>>>>>> Datasheet:
>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>
>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>> ---
>>>>>>>      .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>      1 file changed, 63 insertions(+)
>>>>>>>      create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>
>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>> new file mode 100644
>>>>>>> index 000000000000..9567aa6f7813
>>>>>>> --- /dev/null
>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>> @@ -0,0 +1,63 @@
>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>> +
>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>> +
>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>> +LP5018 supports eighteen strings.
>>>>>>> +
>>>>>>> +Required properties:
>>>>>>> +    - compatible:
>>>>>>> +        "ti,lp5018"
>>>>>>> +        "ti,lp5024"
>>>>>>> +    - reg :  I2C slave address
>>>>>>> +    - #address-cells : 1
>>>>>>> +    - #size-cells : 0
>>>>>>> +
>>>>>>> +Optional properties:
>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>> +    - vled-supply : LED supply
>>>>>>> +
>>>>>>> +Required child properties:
>>>>>>> +    - reg : Is the child node iteration.
>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>> +            LP5018 - 0 - 5
>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>> +            property will contain multiple LED IDs.
>>>>>>> +
>>>>>>> +Optional child properties:
>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>> +    - linux,default-trigger :
>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>> +                led-sources property are grouped within a control
>>>>>>> +                bank for brightness and mixing control.
>>>>>>> +
>>>>>>> +Example:
>>>>>>> +
>>>>>>> +led-controller@28 {
>>>>>>> +    compatible = "ti,lp5024";
>>>>>>> +    reg = <0x28>;
>>>>>>> +    #address-cells = <1>;
>>>>>>> +    #size-cells = <0>;
>>>>>>> +
>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>> +
>>>>>>> +    led@0 {
>>>>>>> +        reg = <0>;
>>>>>>> +        led-sources = <1>;
>>>>>>> +    };
>>>>>>> +
>>>>>>> +    led@1 {
>>>>>>> +        reg = <1>;
>>>>>>> +        led-sources = <0 6>;
>>>>>>> +        ti,control-bank;
>>>>>>
>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>
>>>>>
>>>>> That will work too.
>>>>
>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>
>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>> See the description above of the led-sources
>>>>
>>>> OK, I confused RGB LED modules with banks.
>>>>
>>>> Shouldn't we allow for defining either strings or RGB LED
>>>> triplets somehow then?
>>>>
>>>
>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>> the triplet is controlled via the associated LEDx_brightness register.
>>
>> led-sources should map to iouts directly.
>> So, for RGB LED modules I would expect:
>>
>> LED0: led-sources = <0 1 2>;
>> LED1: led-sources = <3 4 5>;
>> LED2: led-sources = <6 7 8>;
>> and so on.
> 
>>
>> for banks:
>>
>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>
> 
> Ok the led-sources would need to be different then this as I don't define the sources for banks.
> 
> The led-sources for the banks and the individual groups will have different meanings within the same
> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
> it would be controlled by the bank brightness register.
> 
> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
> registers.

Yes, that's why I mentioned the need for validation of led-sources.
But they have to be iouts. This property was introduced specifically
for such purposes.

common LED bindings say:

- led-sources : List of device current outputs the LED is connected to. The
                 outputs are identified by the numbers that must be defined
                 in the LED device binding documentation.

>> We could additionally mark banks with ti,control-bank,
> 
> We would have to keep the ti,control-bank node based on the above.
> 
>> but I'm not sure if it would ease parsing, since
>> you will have to validate iouts configuration anyway.
>>
>>> If you have multiple LED sources defined in the led-sources then those LEDs would be grouped in the bank.
>>> I guess I need to provide some protection or a warning if a DT defines two banks because there is only one bank control.
>>
>> Does the hardware allow the IOUT to belong to an RGB LED module
>> and to a bank in the same time?
>>
> 
> No it does not.  LED_CONFIG0 sets the bit if it is control bank or not.

OK, so validation will also have to check if led-sources definitions
are not mutually exclusive between child DT nodes. For consistency it
would be really better if bank definitions also used led-sources.

> Section 8.3.2 in the data sheet says
> "When a channel is configured in
> LED bank-control mode, the related color mixing and intensity control is governed by the bank control registers
> (BANK_A_COLOR, BANK_B_COLOR, BANK_C_COLOR, and BANK_BRIGHTNESS) regardless of the inputs
> on its own color-mixing and intensity-control registers."
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-09 21:28               ` Jacek Anaszewski
@ 2019-01-09 21:31                 ` Dan Murphy
  2019-01-10 18:44                   ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-09 21:31 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
> On 1/9/19 10:12 PM, Dan Murphy wrote:
>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>> Hi Dan,
>>>
>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>> Jacek
>>>>>>
>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>> Dan,
>>>>>>>
>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>
>>>>>>>> Datasheet:
>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>
>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>> ---
>>>>>>>>      .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>      1 file changed, 63 insertions(+)
>>>>>>>>      create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>
>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>> new file mode 100644
>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>> +
>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>> +
>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>> +
>>>>>>>> +Required properties:
>>>>>>>> +    - compatible:
>>>>>>>> +        "ti,lp5018"
>>>>>>>> +        "ti,lp5024"
>>>>>>>> +    - reg :  I2C slave address
>>>>>>>> +    - #address-cells : 1
>>>>>>>> +    - #size-cells : 0
>>>>>>>> +
>>>>>>>> +Optional properties:
>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>> +    - vled-supply : LED supply
>>>>>>>> +
>>>>>>>> +Required child properties:
>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>> +
>>>>>>>> +Optional child properties:
>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>> +    - linux,default-trigger :
>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>> +
>>>>>>>> +Example:
>>>>>>>> +
>>>>>>>> +led-controller@28 {
>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>> +    reg = <0x28>;
>>>>>>>> +    #address-cells = <1>;
>>>>>>>> +    #size-cells = <0>;
>>>>>>>> +
>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>> +
>>>>>>>> +    led@0 {
>>>>>>>> +        reg = <0>;
>>>>>>>> +        led-sources = <1>;
>>>>>>>> +    };
>>>>>>>> +
>>>>>>>> +    led@1 {
>>>>>>>> +        reg = <1>;
>>>>>>>> +        led-sources = <0 6>;
>>>>>>>> +        ti,control-bank;
>>>>>>>
>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>
>>>>>>
>>>>>> That will work too.
>>>>>
>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>
>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>> See the description above of the led-sources
>>>>>
>>>>> OK, I confused RGB LED modules with banks.
>>>>>
>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>> triplets somehow then?
>>>>>
>>>>
>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>
>>> led-sources should map to iouts directly.
>>> So, for RGB LED modules I would expect:
>>>
>>> LED0: led-sources = <0 1 2>;
>>> LED1: led-sources = <3 4 5>;
>>> LED2: led-sources = <6 7 8>;
>>> and so on.
>>
>>>
>>> for banks:
>>>
>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>
>>
>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>
>> The led-sources for the banks and the individual groups will have different meanings within the same
>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>> it would be controlled by the bank brightness register.
>>
>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>> registers.
> 
> Yes, that's why I mentioned the need for validation of led-sources.
> But they have to be iouts. This property was introduced specifically
> for such purposes.
> 

Yes Pavel also mentioned that as well.

I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.

Dan

> common LED bindings say:
> 
> - led-sources : List of device current outputs the LED is connected to. The
>                 outputs are identified by the numbers that must be defined
>                 in the LED device binding documentation.
> 
>>> We could additionally mark banks with ti,control-bank,
>>
>> We would have to keep the ti,control-bank node based on the above.
>>
>>> but I'm not sure if it would ease parsing, since
>>> you will have to validate iouts configuration anyway.
>>>
>>>> If you have multiple LED sources defined in the led-sources then those LEDs would be grouped in the bank.
>>>> I guess I need to provide some protection or a warning if a DT defines two banks because there is only one bank control.
>>>
>>> Does the hardware allow the IOUT to belong to an RGB LED module
>>> and to a bank in the same time?
>>>
>>
>> No it does not.  LED_CONFIG0 sets the bit if it is control bank or not.
> 
> OK, so validation will also have to check if led-sources definitions
> are not mutually exclusive between child DT nodes. For consistency it
> would be really better if bank definitions also used led-sources.
> 
>> Section 8.3.2 in the data sheet says
>> "When a channel is configured in
>> LED bank-control mode, the related color mixing and intensity control is governed by the bank control registers
>> (BANK_A_COLOR, BANK_B_COLOR, BANK_C_COLOR, and BANK_BRIGHTNESS) regardless of the inputs
>> on its own color-mixing and intensity-control registers."
>>
> 


-- 
------------------
Dan Murphy

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-08 21:25                                                   ` Dan Murphy
@ 2019-01-10 12:46                                                     ` Dan Murphy
  2019-01-10 19:23                                                       ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-10 12:46 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

Jacek

On 1/8/19 3:25 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/8/19 3:18 PM, Jacek Anaszewski wrote:
>> Hi Dan,
>>
>> On 1/7/19 10:14 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/7/19 2:59 PM, Jacek Anaszewski wrote:
>>>> Dan,
>>>>
>>>> On 1/7/19 8:36 PM, Dan Murphy wrote:
>>>>> Jacek
>>>>>
>>>>> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>>>>>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>>>>>> Hi Pavel,
>>>>>>>
>>>>>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>>>>>> Hi!
>>>>>>>>
>>>>>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>>>>>> problems are. It is hard to explain colors over email...
>>>>>>>>>
>>>>>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>>>>>
>>>>>>>>> I don't see any problems in exposing separate red,green,blue
>>>>>>>>> files and brightness for the devices with hardware support for
>>>>>>>>> that.
>>>>>>>>
>>>>>>>> Well, that's what we do today, as three separate LEDs, right?
>>>>>>>
>>>>>>> No. It doesn't allow for setting color intensity by having
>>>>>>> the color fixed beforehand. Below is relevant excerpt from
>>>>>>> the lp5024 documentation. This is not something that can be
>>>>>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>>>>>> reservation that the hardware implementation uses PWM
>>>>>>> for setting color intensity.
>>>>>>>
>>>>>>> <quote>
>>>>>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>>>>>
>>>>>>> When color is fixed, the independent intensity-control is used to
>>>>>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>>>>>
>>>>>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>>>>>
>>>>>>> Every three consecutive output channels are assigned to their respective
>>>>>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>>>>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>>>>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>>>>>> device allows 256-step intensity control for each RGB LED module, which
>>>>>>> helps achieve a smooth dimming effect.
>>>>>>> </quote>
>>>>>>>
>>>>>>>> I don't have problem with that, either; other drivers already do
>>>>>>>> that. He's free to use existing same interface.
>>>>>>>>
>>>>>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>>>>>> turning led "white".
>>>>>>>>
>>>>>>>> So... perhaps we should agree on requirements, first, and then we can
>>>>>>>> discuss solutions?
>>>>>>>>
>>>>>>>> Requirements for RGB LED interface:
>>>>>>>>
>>>>>>>> 1) Userspace should be able to set the white color
>>>>>>>>
>>>>>>>> 2) Userspace should be able to arbitrary color from well known list
>>>>>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>>>>>
>>>>>>> The difference is that monitor display driver is pre-calibrated
>>>>>>> for given display by the manufacturer. With the LED controllers the
>>>>>>> manufacturer has no control over what LEDs will be connected to the
>>>>>>> iouts. Therefore it should be not surprising that colors produced
>>>>>>> by custom LEDs are not as user would expect when comparing to
>>>>>>> the RGB color displayed on the monitor display.
>>>>>>>
>>>>>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>>>>>> that show how to produce various patterns with use of the reference
>>>>>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>>>>>
>>>>>>> Document [0] mentions also specific "Design considerations" in the
>>>>>>> chapter 2.2:
>>>>>>>
>>>>>>> <quote>
>>>>>>> Several considerations are taken into account for this particular design:
>>>>>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>>>>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>>>>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>>>>>
>>>>>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>>>>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>>>>>> specific design.
>>>>>>> </quote>
>>>>>>>
>>>>>>> This renders your requirement 2) infeasible with use of custom LEDs
>>>>>>> any fixed algorithm, since the final effect will always heavily depend
>>>>>>
>>>>>> Typo here: s/any fixed/and fixed/
>>>>>>
>>>>>>> on the LED circuit design.
>>>>>>>
>>>>>>>>
>>>>>>>>        2a) LEDs probably slightly change color as they age. That's out of
>>>>>>>>        scope, unless the variation is much greater than on monitors.
>>>>>>>>
>>>>>>>>        2b) Manufacturing differences cause small color variation. Again,
>>>>>>>>        that's out of scope, unless the variation is much greater than on
>>>>>>>>        monitors.
>>>>>>>>
>>>>>>>> Nice to have features:
>>>>>>>>
>>>>>>>> 3) Full range of available colors/intensities should be available to
>>>>>>>> userspace
>>>>>>>>
>>>>>>>> 4) Interface should work well with existing triggers
>>>>>>>>
>>>>>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>>>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>>>>>> variations).
>>>>>>>>
>>>>>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>>>>>> should be integer or fixed point
>>>>>>>>
>>>>>>>> Problems:
>>>>>>>>
>>>>>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>>>>>> red/green/blue channels will result in nothing close to white
>>>>>>>> light. In fact, to get white light on N900, blue and green channel's
>>>>>>>> PWM needs to be set pretty low, as in 5%.
>>>>>>>>
>>>>>>>> b) LED class does not define any relation between "brightness" in
>>>>>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>>>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>>>>>> of lumens. RGB color model uses even more complex function.
>>>>>>>>
>>>>>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>>>>>> wavelength of light, while CRTs and LCDs produce broader
>>>>>>>> spectrums.
>>>>>>>>
>>>>>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>>>>>
>>>>>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>>>>>> differences will exist for other colors.
>>>>>>>>
>>>>>>>> f) We have existing RGB LEDs represented as three separate
>>>>>>>> monochromatic LEDs in sysfs.
>>>>>>>
>>>>>>> One general question: do you have any solutions in store?
>>>>>>>
>>>>>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>>>>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>>>>>
>>>>>>
>>>>>
>>>>> I just wanted to point out that there are 4 total devices right now that use the same mapping
>>>>>
>>>>> LP5018, LP5024, LP5030 and the LP5036.
>>>>>
>>>>> I can implement what ever we would like to I just need to know what to design against.
>>>>
>>>> As you can see from the discussion in this thread it may take some
>>>> time to work out the interface satisfying everyone. I made some design
>>>> proposal, but Pavel had no warm word for it. It would be easier if
>>>> we had more opinions.
>>>
>>> I got it from the threads and just the time invested in the FW and HSV.
>>>
>>>>
>>>> How do you feel about using brightness file for setting LEDn_BRIGHTNESS?
>>>
>>> I am using that now.  The brightness file will adjust the overall brightness of the LED group
>>> or bank pending on how the LEDs are grouped in the DT file.
>>>
>>>>
>>>> Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
>>>> increasing color lightness (i.e. the pattern presented in the video [0]
>>>> starting from 1:22)?
>>>
>>> No unfortunately this is why I introduced the new files to control the individual RGB intensities
>>> so that the designers can set, tune, create color variations or patterns like the video.
>>>
>>> The RGB group brightness would be independent based on lighting conditions, enclosures and diffusers.
>>> So you could technically be changing color and overall brightness virtually simultaneously
>>
>> Oh, so this is surprising. Now it gets even more obscure to me.
>>
>> It would be really helpful if we could see a video showing
>> the LED effects with regard to the applied settings.
> 
> Well I am doing a test off the command line to ensure the user space can interface with the RGB LED.
> 
> I can ping someone in product development to see the application of this device if that would help.
> We did give them a test driver to work on their features but told them the driver is not final until it
> is in the mainline kernel
> 
> Dan
> 
>>
>>>>> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.
>>>>
>>>> Do what you deem most suitable for you. We are here only to help
>>>> merging the patches, but keeping in mind that kernel interface once
>>>> introduced must be preserved forever. Therefore we need to do our
>>>> best to make the best possible design decisions.
>>>>
>>>> [0] https://www.youtube.com/watch?v=qdt-alh8i6E
>>>>
>>>
>>> I understand.  Maybe I can make the files generic to use for either control or individual control.
>>>
>>> We can probably define new ABI's until either HSV or DT frameworks get going.  And them make the file presentation
>>> configurable and default to the new files.
>>
>> I am leaning towards it. Just commented on your patches.
>>
> 
> 

Asked the HW team for videos this is what they sent
https://training.ti.com/lp50x-led-drivers-achieve-optimal-color-brightness-zero-audible-noise
https://training.ti.com/how-configuring-led-brightness-color-and-patterns-lp50x-gui-tool

Not sure how helpful these would be

Dan

-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-09 21:31                 ` Dan Murphy
@ 2019-01-10 18:44                   ` Jacek Anaszewski
  2019-01-10 19:22                     ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-10 18:44 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Hi Dan,

On 1/9/19 10:31 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>> Hi Dan,
>>>>
>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>> Jacek
>>>>>>>
>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>> Dan,
>>>>>>>>
>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>
>>>>>>>>> Datasheet:
>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>
>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>> ---
>>>>>>>>>       .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>       1 file changed, 63 insertions(+)
>>>>>>>>>       create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>
>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>> new file mode 100644
>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>> --- /dev/null
>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>> +
>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>> +
>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>> +
>>>>>>>>> +Required properties:
>>>>>>>>> +    - compatible:
>>>>>>>>> +        "ti,lp5018"
>>>>>>>>> +        "ti,lp5024"
>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>> +    - #address-cells : 1
>>>>>>>>> +    - #size-cells : 0
>>>>>>>>> +
>>>>>>>>> +Optional properties:
>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>> +
>>>>>>>>> +Required child properties:
>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>> +
>>>>>>>>> +Optional child properties:
>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>> +
>>>>>>>>> +Example:
>>>>>>>>> +
>>>>>>>>> +led-controller@28 {
>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>> +    reg = <0x28>;
>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>> +
>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>> +
>>>>>>>>> +    led@0 {
>>>>>>>>> +        reg = <0>;
>>>>>>>>> +        led-sources = <1>;
>>>>>>>>> +    };
>>>>>>>>> +
>>>>>>>>> +    led@1 {
>>>>>>>>> +        reg = <1>;
>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>> +        ti,control-bank;
>>>>>>>>
>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>
>>>>>>>
>>>>>>> That will work too.
>>>>>>
>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>
>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>> See the description above of the led-sources
>>>>>>
>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>
>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>> triplets somehow then?
>>>>>>
>>>>>
>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>
>>>> led-sources should map to iouts directly.
>>>> So, for RGB LED modules I would expect:
>>>>
>>>> LED0: led-sources = <0 1 2>;
>>>> LED1: led-sources = <3 4 5>;
>>>> LED2: led-sources = <6 7 8>;
>>>> and so on.
>>>
>>>>
>>>> for banks:
>>>>
>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>
>>>
>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>
>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>> it would be controlled by the bank brightness register.
>>>
>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>> registers.
>>
>> Yes, that's why I mentioned the need for validation of led-sources.
>> But they have to be iouts. This property was introduced specifically
>> for such purposes.
>>
> 
> Yes Pavel also mentioned that as well.
> 
> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.

Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
I have an impression that it defines whether LED belongs to an RGB LED
module or to a bank. Basing on that I created my DT example above.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-10 18:44                   ` Jacek Anaszewski
@ 2019-01-10 19:22                     ` Dan Murphy
  2019-01-10 19:57                       ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-10 19:22 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
> Hi Dan,
> 
> On 1/9/19 10:31 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>> Hi Dan,
>>>>>
>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>> Jacek
>>>>>>>>
>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>> Dan,
>>>>>>>>>
>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>
>>>>>>>>>> Datasheet:
>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>> ---
>>>>>>>>>>       .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>       1 file changed, 63 insertions(+)
>>>>>>>>>>       create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>
>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>> new file mode 100644
>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>> --- /dev/null
>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>> +
>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>> +
>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>> +
>>>>>>>>>> +Required properties:
>>>>>>>>>> +    - compatible:
>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>> +
>>>>>>>>>> +Optional properties:
>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>> +
>>>>>>>>>> +Required child properties:
>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>> +
>>>>>>>>>> +Optional child properties:
>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>> +
>>>>>>>>>> +Example:
>>>>>>>>>> +
>>>>>>>>>> +led-controller@28 {
>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>> +
>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>> +
>>>>>>>>>> +    led@0 {
>>>>>>>>>> +        reg = <0>;
>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>> +    };
>>>>>>>>>> +
>>>>>>>>>> +    led@1 {
>>>>>>>>>> +        reg = <1>;
>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>
>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>
>>>>>>>>
>>>>>>>> That will work too.
>>>>>>>
>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>
>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>> See the description above of the led-sources
>>>>>>>
>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>
>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>> triplets somehow then?
>>>>>>>
>>>>>>
>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>
>>>>> led-sources should map to iouts directly.
>>>>> So, for RGB LED modules I would expect:
>>>>>
>>>>> LED0: led-sources = <0 1 2>;
>>>>> LED1: led-sources = <3 4 5>;
>>>>> LED2: led-sources = <6 7 8>;
>>>>> and so on.
>>>>
>>>>>
>>>>> for banks:
>>>>>
>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>
>>>>
>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>
>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>> it would be controlled by the bank brightness register.
>>>>
>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>> registers.
>>>
>>> Yes, that's why I mentioned the need for validation of led-sources.
>>> But they have to be iouts. This property was introduced specifically
>>> for such purposes.
>>>
>>
>> Yes Pavel also mentioned that as well.
>>
>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
> 
> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
> I have an impression that it defines whether LED belongs to an RGB LED
> module or to a bank. Basing on that I created my DT example above.
> 

Yes so if you turn on the bank control for LED0 and LED1 then 
out 0, 3 are mapped to BANK A
out 1, 4 are mapped to BANK B
out 2, 5 are mapped to BANK C

All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness

If we grouped the LEDs into a bank the led-sources would look more like this
led-sources = < 0 1 2 3 4 5 >;
ti,control-bank; // But this can be omitted as led-sources is greater then 3

non-banked case would be
led-sources = < 0 1 2 >;

But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
are inherently mapped to the bank.  They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
when banked it treats the groups of RGBs that are defined as a single LED.

This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
LED file presented to the user space.

Dan

-- 
------------------
Dan Murphy

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-10 12:46                                                     ` Dan Murphy
@ 2019-01-10 19:23                                                       ` Jacek Anaszewski
  2019-01-10 19:58                                                         ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-10 19:23 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

Dan,

On 1/10/19 1:46 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/8/19 3:25 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/8/19 3:18 PM, Jacek Anaszewski wrote:
>>> Hi Dan,
>>>
>>> On 1/7/19 10:14 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/7/19 2:59 PM, Jacek Anaszewski wrote:
>>>>> Dan,
>>>>>
>>>>> On 1/7/19 8:36 PM, Dan Murphy wrote:
>>>>>> Jacek
>>>>>>
>>>>>> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>>>>>>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>>>>>>> Hi Pavel,
>>>>>>>>
>>>>>>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>>>>>>> Hi!
>>>>>>>>>
>>>>>>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>>>>>>> problems are. It is hard to explain colors over email...
>>>>>>>>>>
>>>>>>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>>>>>>
>>>>>>>>>> I don't see any problems in exposing separate red,green,blue
>>>>>>>>>> files and brightness for the devices with hardware support for
>>>>>>>>>> that.
>>>>>>>>>
>>>>>>>>> Well, that's what we do today, as three separate LEDs, right?
>>>>>>>>
>>>>>>>> No. It doesn't allow for setting color intensity by having
>>>>>>>> the color fixed beforehand. Below is relevant excerpt from
>>>>>>>> the lp5024 documentation. This is not something that can be
>>>>>>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>>>>>>> reservation that the hardware implementation uses PWM
>>>>>>>> for setting color intensity.
>>>>>>>>
>>>>>>>> <quote>
>>>>>>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>>>>>>
>>>>>>>> When color is fixed, the independent intensity-control is used to
>>>>>>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>>>>>>
>>>>>>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>>>>>>
>>>>>>>> Every three consecutive output channels are assigned to their respective
>>>>>>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>>>>>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>>>>>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>>>>>>> device allows 256-step intensity control for each RGB LED module, which
>>>>>>>> helps achieve a smooth dimming effect.
>>>>>>>> </quote>
>>>>>>>>
>>>>>>>>> I don't have problem with that, either; other drivers already do
>>>>>>>>> that. He's free to use existing same interface.
>>>>>>>>>
>>>>>>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>>>>>>> turning led "white".
>>>>>>>>>
>>>>>>>>> So... perhaps we should agree on requirements, first, and then we can
>>>>>>>>> discuss solutions?
>>>>>>>>>
>>>>>>>>> Requirements for RGB LED interface:
>>>>>>>>>
>>>>>>>>> 1) Userspace should be able to set the white color
>>>>>>>>>
>>>>>>>>> 2) Userspace should be able to arbitrary color from well known list
>>>>>>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>>>>>>
>>>>>>>> The difference is that monitor display driver is pre-calibrated
>>>>>>>> for given display by the manufacturer. With the LED controllers the
>>>>>>>> manufacturer has no control over what LEDs will be connected to the
>>>>>>>> iouts. Therefore it should be not surprising that colors produced
>>>>>>>> by custom LEDs are not as user would expect when comparing to
>>>>>>>> the RGB color displayed on the monitor display.
>>>>>>>>
>>>>>>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>>>>>>> that show how to produce various patterns with use of the reference
>>>>>>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>>>>>>
>>>>>>>> Document [0] mentions also specific "Design considerations" in the
>>>>>>>> chapter 2.2:
>>>>>>>>
>>>>>>>> <quote>
>>>>>>>> Several considerations are taken into account for this particular design:
>>>>>>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>>>>>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>>>>>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>>>>>>
>>>>>>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>>>>>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>>>>>>> specific design.
>>>>>>>> </quote>
>>>>>>>>
>>>>>>>> This renders your requirement 2) infeasible with use of custom LEDs
>>>>>>>> any fixed algorithm, since the final effect will always heavily depend
>>>>>>>
>>>>>>> Typo here: s/any fixed/and fixed/
>>>>>>>
>>>>>>>> on the LED circuit design.
>>>>>>>>
>>>>>>>>>
>>>>>>>>>         2a) LEDs probably slightly change color as they age. That's out of
>>>>>>>>>         scope, unless the variation is much greater than on monitors.
>>>>>>>>>
>>>>>>>>>         2b) Manufacturing differences cause small color variation. Again,
>>>>>>>>>         that's out of scope, unless the variation is much greater than on
>>>>>>>>>         monitors.
>>>>>>>>>
>>>>>>>>> Nice to have features:
>>>>>>>>>
>>>>>>>>> 3) Full range of available colors/intensities should be available to
>>>>>>>>> userspace
>>>>>>>>>
>>>>>>>>> 4) Interface should work well with existing triggers
>>>>>>>>>
>>>>>>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>>>>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>>>>>>> variations).
>>>>>>>>>
>>>>>>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>>>>>>> should be integer or fixed point
>>>>>>>>>
>>>>>>>>> Problems:
>>>>>>>>>
>>>>>>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>>>>>>> red/green/blue channels will result in nothing close to white
>>>>>>>>> light. In fact, to get white light on N900, blue and green channel's
>>>>>>>>> PWM needs to be set pretty low, as in 5%.
>>>>>>>>>
>>>>>>>>> b) LED class does not define any relation between "brightness" in
>>>>>>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>>>>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>>>>>>> of lumens. RGB color model uses even more complex function.
>>>>>>>>>
>>>>>>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>>>>>>> wavelength of light, while CRTs and LCDs produce broader
>>>>>>>>> spectrums.
>>>>>>>>>
>>>>>>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>>>>>>
>>>>>>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>>>>>>> differences will exist for other colors.
>>>>>>>>>
>>>>>>>>> f) We have existing RGB LEDs represented as three separate
>>>>>>>>> monochromatic LEDs in sysfs.
>>>>>>>>
>>>>>>>> One general question: do you have any solutions in store?
>>>>>>>>
>>>>>>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>>>>>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>> I just wanted to point out that there are 4 total devices right now that use the same mapping
>>>>>>
>>>>>> LP5018, LP5024, LP5030 and the LP5036.
>>>>>>
>>>>>> I can implement what ever we would like to I just need to know what to design against.
>>>>>
>>>>> As you can see from the discussion in this thread it may take some
>>>>> time to work out the interface satisfying everyone. I made some design
>>>>> proposal, but Pavel had no warm word for it. It would be easier if
>>>>> we had more opinions.
>>>>
>>>> I got it from the threads and just the time invested in the FW and HSV.
>>>>
>>>>>
>>>>> How do you feel about using brightness file for setting LEDn_BRIGHTNESS?
>>>>
>>>> I am using that now.  The brightness file will adjust the overall brightness of the LED group
>>>> or bank pending on how the LEDs are grouped in the DT file.
>>>>
>>>>>
>>>>> Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
>>>>> increasing color lightness (i.e. the pattern presented in the video [0]
>>>>> starting from 1:22)?
>>>>
>>>> No unfortunately this is why I introduced the new files to control the individual RGB intensities
>>>> so that the designers can set, tune, create color variations or patterns like the video.
>>>>
>>>> The RGB group brightness would be independent based on lighting conditions, enclosures and diffusers.
>>>> So you could technically be changing color and overall brightness virtually simultaneously
>>>
>>> Oh, so this is surprising. Now it gets even more obscure to me.
>>>
>>> It would be really helpful if we could see a video showing
>>> the LED effects with regard to the applied settings.
>>
>> Well I am doing a test off the command line to ensure the user space can interface with the RGB LED.
>>
>> I can ping someone in product development to see the application of this device if that would help.
>> We did give them a test driver to work on their features but told them the driver is not final until it
>> is in the mainline kernel
>>
>> Dan
>>
>>>
>>>>>> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.
>>>>>
>>>>> Do what you deem most suitable for you. We are here only to help
>>>>> merging the patches, but keeping in mind that kernel interface once
>>>>> introduced must be preserved forever. Therefore we need to do our
>>>>> best to make the best possible design decisions.
>>>>>
>>>>> [0] https://www.youtube.com/watch?v=qdt-alh8i6E
>>>>>
>>>>
>>>> I understand.  Maybe I can make the files generic to use for either control or individual control.
>>>>
>>>> We can probably define new ABI's until either HSV or DT frameworks get going.  And them make the file presentation
>>>> configurable and default to the new files.
>>>
>>> I am leaning towards it. Just commented on your patches.
>>>
>>
>>
> 
> Asked the HW team for videos this is what they sent
> https://training.ti.com/lp50x-led-drivers-achieve-optimal-color-brightness-zero-audible-noise
> https://training.ti.com/how-configuring-led-brightness-color-and-patterns-lp50x-gui-tool
> 
> Not sure how helpful these would be

Thank you for the videos - they are helpful, and they confirm my first
impression regarding the LEDn_BRIGHTNESS effect. In is shown in the
second video starting from 3:37.

This is the same what I was asking about previously (video [0] from
previous message starting from 1:22). For me this looks similarly
to increasing V of HSV or L of HSL [1].

You denied, so either we interpret colors differently, or there was
some misunderstanding.

[1] http://hslpicker.com

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-10 19:22                     ` Dan Murphy
@ 2019-01-10 19:57                       ` Jacek Anaszewski
  2019-01-10 20:43                         ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-10 19:57 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Dan,

On 1/10/19 8:22 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>> Hi Dan,
>>
>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>> Hi Dan,
>>>>>>
>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>> Jacek
>>>>>>>>>
>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>> Dan,
>>>>>>>>>>
>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>
>>>>>>>>>>> Datasheet:
>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>> ---
>>>>>>>>>>>        .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>        1 file changed, 63 insertions(+)
>>>>>>>>>>>        create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>> new file mode 100644
>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>> --- /dev/null
>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>> +
>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>> +
>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>> +
>>>>>>>>>>> +Required properties:
>>>>>>>>>>> +    - compatible:
>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>> +
>>>>>>>>>>> +Optional properties:
>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>> +
>>>>>>>>>>> +Required child properties:
>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>> +
>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>> +
>>>>>>>>>>> +Example:
>>>>>>>>>>> +
>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>> +
>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>> +
>>>>>>>>>>> +    led@0 {
>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>> +    };
>>>>>>>>>>> +
>>>>>>>>>>> +    led@1 {
>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>
>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> That will work too.
>>>>>>>>
>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>
>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>> See the description above of the led-sources
>>>>>>>>
>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>
>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>> triplets somehow then?
>>>>>>>>
>>>>>>>
>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>
>>>>>> led-sources should map to iouts directly.
>>>>>> So, for RGB LED modules I would expect:
>>>>>>
>>>>>> LED0: led-sources = <0 1 2>;
>>>>>> LED1: led-sources = <3 4 5>;
>>>>>> LED2: led-sources = <6 7 8>;
>>>>>> and so on.
>>>>>
>>>>>>
>>>>>> for banks:
>>>>>>
>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>
>>>>>
>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>
>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>> it would be controlled by the bank brightness register.
>>>>>
>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>> registers.
>>>>
>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>> But they have to be iouts. This property was introduced specifically
>>>> for such purposes.
>>>>
>>>
>>> Yes Pavel also mentioned that as well.
>>>
>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>
>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>> I have an impression that it defines whether LED belongs to an RGB LED
>> module or to a bank. Basing on that I created my DT example above.
>>
> 
> Yes so if you turn on the bank control for LED0 and LED1 then
> out 0, 3 are mapped to BANK A
> out 1, 4 are mapped to BANK B

Just noticed that I made a mistake in my example, it should have been:

Bank B with iouts 1,4,10:  led-sources<1 4 10>;

> out 2, 5 are mapped to BANK C

Correct.

> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness

That's right.

> If we grouped the LEDs into a bank the led-sources would look more like this
> led-sources = < 0 1 2 3 4 5 >;

Why? This would be a mix of three banks. Like you listed above.
I'm still interpreting led-sources elements as iout identifiers.

> ti,control-bank; // But this can be omitted as led-sources is greater then 3
> 
> non-banked case would be
> led-sources = < 0 1 2 >;

Agreed here. It would be LED0 RGB LED module.
> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
> are inherently mapped to the bank.  

To three separate banks, right?
OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.

> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
> when banked it treats the groups of RGBs that are defined as a single LED.
> 
> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
> LED file presented to the user space.

I suspect there is logical clash here due to interpreting
led-sources elements as iouts in one case and LEDn modules
in the other case.

-- 
Best regards,
Jacek Anaszewski

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-10 19:23                                                       ` Jacek Anaszewski
@ 2019-01-10 19:58                                                         ` Dan Murphy
  2019-01-10 21:02                                                           ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-10 19:58 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

On 1/10/19 1:23 PM, Jacek Anaszewski wrote:
> Dan,
> 
> On 1/10/19 1:46 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/8/19 3:25 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/8/19 3:18 PM, Jacek Anaszewski wrote:
>>>> Hi Dan,
>>>>
>>>> On 1/7/19 10:14 PM, Dan Murphy wrote:
>>>>> Jacek
>>>>>
>>>>> On 1/7/19 2:59 PM, Jacek Anaszewski wrote:
>>>>>> Dan,
>>>>>>
>>>>>> On 1/7/19 8:36 PM, Dan Murphy wrote:
>>>>>>> Jacek
>>>>>>>
>>>>>>> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>>>>>>>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>>>>>>>> Hi Pavel,
>>>>>>>>>
>>>>>>>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>>>>>>>> Hi!
>>>>>>>>>>
>>>>>>>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>>>>>>>> problems are. It is hard to explain colors over email...
>>>>>>>>>>>
>>>>>>>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>>>>>>>
>>>>>>>>>>> I don't see any problems in exposing separate red,green,blue
>>>>>>>>>>> files and brightness for the devices with hardware support for
>>>>>>>>>>> that.
>>>>>>>>>>
>>>>>>>>>> Well, that's what we do today, as three separate LEDs, right?
>>>>>>>>>
>>>>>>>>> No. It doesn't allow for setting color intensity by having
>>>>>>>>> the color fixed beforehand. Below is relevant excerpt from
>>>>>>>>> the lp5024 documentation. This is not something that can be
>>>>>>>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>>>>>>>> reservation that the hardware implementation uses PWM
>>>>>>>>> for setting color intensity.
>>>>>>>>>
>>>>>>>>> <quote>
>>>>>>>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>>>>>>>
>>>>>>>>> When color is fixed, the independent intensity-control is used to
>>>>>>>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>>>>>>>
>>>>>>>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>>>>>>>
>>>>>>>>> Every three consecutive output channels are assigned to their respective
>>>>>>>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>>>>>>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>>>>>>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>>>>>>>> device allows 256-step intensity control for each RGB LED module, which
>>>>>>>>> helps achieve a smooth dimming effect.
>>>>>>>>> </quote>
>>>>>>>>>
>>>>>>>>>> I don't have problem with that, either; other drivers already do
>>>>>>>>>> that. He's free to use existing same interface.
>>>>>>>>>>
>>>>>>>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>>>>>>>> turning led "white".
>>>>>>>>>>
>>>>>>>>>> So... perhaps we should agree on requirements, first, and then we can
>>>>>>>>>> discuss solutions?
>>>>>>>>>>
>>>>>>>>>> Requirements for RGB LED interface:
>>>>>>>>>>
>>>>>>>>>> 1) Userspace should be able to set the white color
>>>>>>>>>>
>>>>>>>>>> 2) Userspace should be able to arbitrary color from well known list
>>>>>>>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>>>>>>>
>>>>>>>>> The difference is that monitor display driver is pre-calibrated
>>>>>>>>> for given display by the manufacturer. With the LED controllers the
>>>>>>>>> manufacturer has no control over what LEDs will be connected to the
>>>>>>>>> iouts. Therefore it should be not surprising that colors produced
>>>>>>>>> by custom LEDs are not as user would expect when comparing to
>>>>>>>>> the RGB color displayed on the monitor display.
>>>>>>>>>
>>>>>>>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>>>>>>>> that show how to produce various patterns with use of the reference
>>>>>>>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>>>>>>>
>>>>>>>>> Document [0] mentions also specific "Design considerations" in the
>>>>>>>>> chapter 2.2:
>>>>>>>>>
>>>>>>>>> <quote>
>>>>>>>>> Several considerations are taken into account for this particular design:
>>>>>>>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>>>>>>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>>>>>>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>>>>>>>
>>>>>>>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>>>>>>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>>>>>>>> specific design.
>>>>>>>>> </quote>
>>>>>>>>>
>>>>>>>>> This renders your requirement 2) infeasible with use of custom LEDs
>>>>>>>>> any fixed algorithm, since the final effect will always heavily depend
>>>>>>>>
>>>>>>>> Typo here: s/any fixed/and fixed/
>>>>>>>>
>>>>>>>>> on the LED circuit design.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>         2a) LEDs probably slightly change color as they age. That's out of
>>>>>>>>>>         scope, unless the variation is much greater than on monitors.
>>>>>>>>>>
>>>>>>>>>>         2b) Manufacturing differences cause small color variation. Again,
>>>>>>>>>>         that's out of scope, unless the variation is much greater than on
>>>>>>>>>>         monitors.
>>>>>>>>>>
>>>>>>>>>> Nice to have features:
>>>>>>>>>>
>>>>>>>>>> 3) Full range of available colors/intensities should be available to
>>>>>>>>>> userspace
>>>>>>>>>>
>>>>>>>>>> 4) Interface should work well with existing triggers
>>>>>>>>>>
>>>>>>>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>>>>>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>>>>>>>> variations).
>>>>>>>>>>
>>>>>>>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>>>>>>>> should be integer or fixed point
>>>>>>>>>>
>>>>>>>>>> Problems:
>>>>>>>>>>
>>>>>>>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>>>>>>>> red/green/blue channels will result in nothing close to white
>>>>>>>>>> light. In fact, to get white light on N900, blue and green channel's
>>>>>>>>>> PWM needs to be set pretty low, as in 5%.
>>>>>>>>>>
>>>>>>>>>> b) LED class does not define any relation between "brightness" in
>>>>>>>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>>>>>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>>>>>>>> of lumens. RGB color model uses even more complex function.
>>>>>>>>>>
>>>>>>>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>>>>>>>> wavelength of light, while CRTs and LCDs produce broader
>>>>>>>>>> spectrums.
>>>>>>>>>>
>>>>>>>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>>>>>>>
>>>>>>>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>>>>>>>> differences will exist for other colors.
>>>>>>>>>>
>>>>>>>>>> f) We have existing RGB LEDs represented as three separate
>>>>>>>>>> monochromatic LEDs in sysfs.
>>>>>>>>>
>>>>>>>>> One general question: do you have any solutions in store?
>>>>>>>>>
>>>>>>>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>>>>>>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>> I just wanted to point out that there are 4 total devices right now that use the same mapping
>>>>>>>
>>>>>>> LP5018, LP5024, LP5030 and the LP5036.
>>>>>>>
>>>>>>> I can implement what ever we would like to I just need to know what to design against.
>>>>>>
>>>>>> As you can see from the discussion in this thread it may take some
>>>>>> time to work out the interface satisfying everyone. I made some design
>>>>>> proposal, but Pavel had no warm word for it. It would be easier if
>>>>>> we had more opinions.
>>>>>
>>>>> I got it from the threads and just the time invested in the FW and HSV.
>>>>>
>>>>>>
>>>>>> How do you feel about using brightness file for setting LEDn_BRIGHTNESS?
>>>>>
>>>>> I am using that now.  The brightness file will adjust the overall brightness of the LED group
>>>>> or bank pending on how the LEDs are grouped in the DT file.
>>>>>
>>>>>>
>>>>>> Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
>>>>>> increasing color lightness (i.e. the pattern presented in the video [0]
>>>>>> starting from 1:22)?
>>>>>
>>>>> No unfortunately this is why I introduced the new files to control the individual RGB intensities
>>>>> so that the designers can set, tune, create color variations or patterns like the video.
>>>>>
>>>>> The RGB group brightness would be independent based on lighting conditions, enclosures and diffusers.
>>>>> So you could technically be changing color and overall brightness virtually simultaneously
>>>>
>>>> Oh, so this is surprising. Now it gets even more obscure to me.
>>>>
>>>> It would be really helpful if we could see a video showing
>>>> the LED effects with regard to the applied settings.
>>>
>>> Well I am doing a test off the command line to ensure the user space can interface with the RGB LED.
>>>
>>> I can ping someone in product development to see the application of this device if that would help.
>>> We did give them a test driver to work on their features but told them the driver is not final until it
>>> is in the mainline kernel
>>>
>>> Dan
>>>
>>>>
>>>>>>> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.
>>>>>>
>>>>>> Do what you deem most suitable for you. We are here only to help
>>>>>> merging the patches, but keeping in mind that kernel interface once
>>>>>> introduced must be preserved forever. Therefore we need to do our
>>>>>> best to make the best possible design decisions.
>>>>>>
>>>>>> [0] https://www.youtube.com/watch?v=qdt-alh8i6E
>>>>>>
>>>>>
>>>>> I understand.  Maybe I can make the files generic to use for either control or individual control.
>>>>>
>>>>> We can probably define new ABI's until either HSV or DT frameworks get going.  And them make the file presentation
>>>>> configurable and default to the new files.
>>>>
>>>> I am leaning towards it. Just commented on your patches.
>>>>
>>>
>>>
>>
>> Asked the HW team for videos this is what they sent
>> https://training.ti.com/lp50x-led-drivers-achieve-optimal-color-brightness-zero-audible-noise
>> https://training.ti.com/how-configuring-led-brightness-color-and-patterns-lp50x-gui-tool
>>
>> Not sure how helpful these would be
> 
> Thank you for the videos - they are helpful, and they confirm my first
> impression regarding the LEDn_BRIGHTNESS effect. In is shown in the
> second video starting from 3:37.
> 
> This is the same what I was asking about previously (video [0] from
> previous message starting from 1:22). For me this looks similarly
> to increasing V of HSV or L of HSL [1].
> 
> You denied, so either we interpret colors differently, or there was
> some misunderstanding.
> 
> [1] http://hslpicker.com
> 

Well I did indicate later that I could work on implementing against the HSV/RGB framework and fit that into
the LP5024 driver.  Only issue I see is mapping of the LED color to the correct output.  I know what is recommended
in the data sheet but that does not mean that is what the developers will do.  We cannot always guarantee that
the red LEDs will be on OUT0, OUT3, OUT6 or on BANK A

But it is not part of the LED class yet I would have to pull in the patch to enable it.

What is the thought on this?  Would the HSV/RGB class be pulled in as a part of the LP5024 driver?
I don't want to put to much effort into code that will have to wait.

Dan

-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-10 19:57                       ` Jacek Anaszewski
@ 2019-01-10 20:43                         ` Dan Murphy
  2019-01-10 22:03                           ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-10 20:43 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
> Dan,
> 
> On 1/10/19 8:22 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>> Hi Dan,
>>>
>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>> Hi Dan,
>>>>>>>
>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>> Jacek
>>>>>>>>>>
>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>> Dan,
>>>>>>>>>>>
>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>
>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>
>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>> ---
>>>>>>>>>>>>        .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>        1 file changed, 63 insertions(+)
>>>>>>>>>>>>        create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>
>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>> +
>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>> +
>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>> +
>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>> +
>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>> +
>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>> +
>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>> +
>>>>>>>>>>>> +Example:
>>>>>>>>>>>> +
>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>> +
>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>> +
>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>> +    };
>>>>>>>>>>>> +
>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>
>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> That will work too.
>>>>>>>>>
>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>
>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>
>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>
>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>> triplets somehow then?
>>>>>>>>>
>>>>>>>>
>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>
>>>>>>> led-sources should map to iouts directly.
>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>
>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>> and so on.
>>>>>>
>>>>>>>
>>>>>>> for banks:
>>>>>>>
>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>
>>>>>>
>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>
>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>> it would be controlled by the bank brightness register.
>>>>>>
>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>> registers.
>>>>>
>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>> But they have to be iouts. This property was introduced specifically
>>>>> for such purposes.
>>>>>
>>>>
>>>> Yes Pavel also mentioned that as well.
>>>>
>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>
>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>> I have an impression that it defines whether LED belongs to an RGB LED
>>> module or to a bank. Basing on that I created my DT example above.
>>>
>>
>> Yes so if you turn on the bank control for LED0 and LED1 then
>> out 0, 3 are mapped to BANK A
>> out 1, 4 are mapped to BANK B
> 
> Just noticed that I made a mistake in my example, it should have been:
> 
> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
> 
>> out 2, 5 are mapped to BANK C
> 
> Correct.
> 
>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
> 
> That's right.
> 
>> If we grouped the LEDs into a bank the led-sources would look more like this
>> led-sources = < 0 1 2 3 4 5 >;
> 
> Why? This would be a mix of three banks. Like you listed above.
> I'm still interpreting led-sources elements as iout identifiers.
> 

I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.

These OUTPUTs will appear as a single RGB LED grouping.

>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>
>> non-banked case would be
>> led-sources = < 0 1 2 >;
> 
> Agreed here. It would be LED0 RGB LED module.
>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>> are inherently mapped to the bank.  
> 
> To three separate banks, right?
> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.

Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
color adjustment registers.

> 
>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>> when banked it treats the groups of RGBs that are defined as a single LED.
>>
>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>> LED file presented to the user space.
> 
> I suspect there is logical clash here due to interpreting
> led-sources elements as iouts in one case and LEDn modules
> in the other case.
> 

Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.

If you define LED0 and LED1 as banked then OUT0->5 are banked and it would be considered a single virtual output.

LED_CONFIG0 even uses the modular approach to define what is banked and what is not.  With the modular approach to led-sources
the mapping of the sources to the CONFIG register become 1-1.

1 = LED7 bank control mode enabled
0 = LED7 independent control mode enabled

-- 
------------------
Dan Murphy

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-10 19:58                                                         ` Dan Murphy
@ 2019-01-10 21:02                                                           ` Jacek Anaszewski
  2019-01-10 21:07                                                             ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-10 21:02 UTC (permalink / raw)
  To: Dan Murphy, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

On 1/10/19 8:58 PM, Dan Murphy wrote:
> On 1/10/19 1:23 PM, Jacek Anaszewski wrote:
>> Dan,
>>
>> On 1/10/19 1:46 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/8/19 3:25 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/8/19 3:18 PM, Jacek Anaszewski wrote:
>>>>> Hi Dan,
>>>>>
>>>>> On 1/7/19 10:14 PM, Dan Murphy wrote:
>>>>>> Jacek
>>>>>>
>>>>>> On 1/7/19 2:59 PM, Jacek Anaszewski wrote:
>>>>>>> Dan,
>>>>>>>
>>>>>>> On 1/7/19 8:36 PM, Dan Murphy wrote:
>>>>>>>> Jacek
>>>>>>>>
>>>>>>>> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>>>>>>>>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>>>>>>>>> Hi Pavel,
>>>>>>>>>>
>>>>>>>>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>>>>>>>>> Hi!
>>>>>>>>>>>
>>>>>>>>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>>>>>>>>> problems are. It is hard to explain colors over email...
>>>>>>>>>>>>
>>>>>>>>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>>>>>>>>
>>>>>>>>>>>> I don't see any problems in exposing separate red,green,blue
>>>>>>>>>>>> files and brightness for the devices with hardware support for
>>>>>>>>>>>> that.
>>>>>>>>>>>
>>>>>>>>>>> Well, that's what we do today, as three separate LEDs, right?
>>>>>>>>>>
>>>>>>>>>> No. It doesn't allow for setting color intensity by having
>>>>>>>>>> the color fixed beforehand. Below is relevant excerpt from
>>>>>>>>>> the lp5024 documentation. This is not something that can be
>>>>>>>>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>>>>>>>>> reservation that the hardware implementation uses PWM
>>>>>>>>>> for setting color intensity.
>>>>>>>>>>
>>>>>>>>>> <quote>
>>>>>>>>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>>>>>>>>
>>>>>>>>>> When color is fixed, the independent intensity-control is used to
>>>>>>>>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>>>>>>>>
>>>>>>>>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>>>>>>>>
>>>>>>>>>> Every three consecutive output channels are assigned to their respective
>>>>>>>>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>>>>>>>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>>>>>>>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>>>>>>>>> device allows 256-step intensity control for each RGB LED module, which
>>>>>>>>>> helps achieve a smooth dimming effect.
>>>>>>>>>> </quote>
>>>>>>>>>>
>>>>>>>>>>> I don't have problem with that, either; other drivers already do
>>>>>>>>>>> that. He's free to use existing same interface.
>>>>>>>>>>>
>>>>>>>>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>>>>>>>>> turning led "white".
>>>>>>>>>>>
>>>>>>>>>>> So... perhaps we should agree on requirements, first, and then we can
>>>>>>>>>>> discuss solutions?
>>>>>>>>>>>
>>>>>>>>>>> Requirements for RGB LED interface:
>>>>>>>>>>>
>>>>>>>>>>> 1) Userspace should be able to set the white color
>>>>>>>>>>>
>>>>>>>>>>> 2) Userspace should be able to arbitrary color from well known list
>>>>>>>>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>>>>>>>>
>>>>>>>>>> The difference is that monitor display driver is pre-calibrated
>>>>>>>>>> for given display by the manufacturer. With the LED controllers the
>>>>>>>>>> manufacturer has no control over what LEDs will be connected to the
>>>>>>>>>> iouts. Therefore it should be not surprising that colors produced
>>>>>>>>>> by custom LEDs are not as user would expect when comparing to
>>>>>>>>>> the RGB color displayed on the monitor display.
>>>>>>>>>>
>>>>>>>>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>>>>>>>>> that show how to produce various patterns with use of the reference
>>>>>>>>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>>>>>>>>
>>>>>>>>>> Document [0] mentions also specific "Design considerations" in the
>>>>>>>>>> chapter 2.2:
>>>>>>>>>>
>>>>>>>>>> <quote>
>>>>>>>>>> Several considerations are taken into account for this particular design:
>>>>>>>>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>>>>>>>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>>>>>>>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>>>>>>>>
>>>>>>>>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>>>>>>>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>>>>>>>>> specific design.
>>>>>>>>>> </quote>
>>>>>>>>>>
>>>>>>>>>> This renders your requirement 2) infeasible with use of custom LEDs
>>>>>>>>>> any fixed algorithm, since the final effect will always heavily depend
>>>>>>>>>
>>>>>>>>> Typo here: s/any fixed/and fixed/
>>>>>>>>>
>>>>>>>>>> on the LED circuit design.
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>          2a) LEDs probably slightly change color as they age. That's out of
>>>>>>>>>>>          scope, unless the variation is much greater than on monitors.
>>>>>>>>>>>
>>>>>>>>>>>          2b) Manufacturing differences cause small color variation. Again,
>>>>>>>>>>>          that's out of scope, unless the variation is much greater than on
>>>>>>>>>>>          monitors.
>>>>>>>>>>>
>>>>>>>>>>> Nice to have features:
>>>>>>>>>>>
>>>>>>>>>>> 3) Full range of available colors/intensities should be available to
>>>>>>>>>>> userspace
>>>>>>>>>>>
>>>>>>>>>>> 4) Interface should work well with existing triggers
>>>>>>>>>>>
>>>>>>>>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>>>>>>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>>>>>>>>> variations).
>>>>>>>>>>>
>>>>>>>>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>>>>>>>>> should be integer or fixed point
>>>>>>>>>>>
>>>>>>>>>>> Problems:
>>>>>>>>>>>
>>>>>>>>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>>>>>>>>> red/green/blue channels will result in nothing close to white
>>>>>>>>>>> light. In fact, to get white light on N900, blue and green channel's
>>>>>>>>>>> PWM needs to be set pretty low, as in 5%.
>>>>>>>>>>>
>>>>>>>>>>> b) LED class does not define any relation between "brightness" in
>>>>>>>>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>>>>>>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>>>>>>>>> of lumens. RGB color model uses even more complex function.
>>>>>>>>>>>
>>>>>>>>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>>>>>>>>> wavelength of light, while CRTs and LCDs produce broader
>>>>>>>>>>> spectrums.
>>>>>>>>>>>
>>>>>>>>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>>>>>>>>
>>>>>>>>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>>>>>>>>> differences will exist for other colors.
>>>>>>>>>>>
>>>>>>>>>>> f) We have existing RGB LEDs represented as three separate
>>>>>>>>>>> monochromatic LEDs in sysfs.
>>>>>>>>>>
>>>>>>>>>> One general question: do you have any solutions in store?
>>>>>>>>>>
>>>>>>>>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>>>>>>>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>> I just wanted to point out that there are 4 total devices right now that use the same mapping
>>>>>>>>
>>>>>>>> LP5018, LP5024, LP5030 and the LP5036.
>>>>>>>>
>>>>>>>> I can implement what ever we would like to I just need to know what to design against.
>>>>>>>
>>>>>>> As you can see from the discussion in this thread it may take some
>>>>>>> time to work out the interface satisfying everyone. I made some design
>>>>>>> proposal, but Pavel had no warm word for it. It would be easier if
>>>>>>> we had more opinions.
>>>>>>
>>>>>> I got it from the threads and just the time invested in the FW and HSV.
>>>>>>
>>>>>>>
>>>>>>> How do you feel about using brightness file for setting LEDn_BRIGHTNESS?
>>>>>>
>>>>>> I am using that now.  The brightness file will adjust the overall brightness of the LED group
>>>>>> or bank pending on how the LEDs are grouped in the DT file.
>>>>>>
>>>>>>>
>>>>>>> Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
>>>>>>> increasing color lightness (i.e. the pattern presented in the video [0]
>>>>>>> starting from 1:22)?
>>>>>>
>>>>>> No unfortunately this is why I introduced the new files to control the individual RGB intensities
>>>>>> so that the designers can set, tune, create color variations or patterns like the video.
>>>>>>
>>>>>> The RGB group brightness would be independent based on lighting conditions, enclosures and diffusers.
>>>>>> So you could technically be changing color and overall brightness virtually simultaneously
>>>>>
>>>>> Oh, so this is surprising. Now it gets even more obscure to me.
>>>>>
>>>>> It would be really helpful if we could see a video showing
>>>>> the LED effects with regard to the applied settings.
>>>>
>>>> Well I am doing a test off the command line to ensure the user space can interface with the RGB LED.
>>>>
>>>> I can ping someone in product development to see the application of this device if that would help.
>>>> We did give them a test driver to work on their features but told them the driver is not final until it
>>>> is in the mainline kernel
>>>>
>>>> Dan
>>>>
>>>>>
>>>>>>>> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.
>>>>>>>
>>>>>>> Do what you deem most suitable for you. We are here only to help
>>>>>>> merging the patches, but keeping in mind that kernel interface once
>>>>>>> introduced must be preserved forever. Therefore we need to do our
>>>>>>> best to make the best possible design decisions.
>>>>>>>
>>>>>>> [0] https://www.youtube.com/watch?v=qdt-alh8i6E
>>>>>>>
>>>>>>
>>>>>> I understand.  Maybe I can make the files generic to use for either control or individual control.
>>>>>>
>>>>>> We can probably define new ABI's until either HSV or DT frameworks get going.  And them make the file presentation
>>>>>> configurable and default to the new files.
>>>>>
>>>>> I am leaning towards it. Just commented on your patches.
>>>>>
>>>>
>>>>
>>>
>>> Asked the HW team for videos this is what they sent
>>> https://training.ti.com/lp50x-led-drivers-achieve-optimal-color-brightness-zero-audible-noise
>>> https://training.ti.com/how-configuring-led-brightness-color-and-patterns-lp50x-gui-tool
>>>
>>> Not sure how helpful these would be
>>
>> Thank you for the videos - they are helpful, and they confirm my first
>> impression regarding the LEDn_BRIGHTNESS effect. In is shown in the
>> second video starting from 3:37.
>>
>> This is the same what I was asking about previously (video [0] from
>> previous message starting from 1:22). For me this looks similarly
>> to increasing V of HSV or L of HSL [1].
>>
>> You denied, so either we interpret colors differently, or there was
>> some misunderstanding.
>>
>> [1] http://hslpicker.com
>>
> 
> Well I did indicate later that I could work on implementing against the HSV/RGB framework and fit that into

I just wanted to make sure that brightness file semantics fits
for this particular LEDn_BRIGHTNESS feature.
Now it is clear to me - yes it does.

For RGB LED modules brightness file would map to LEDn_BRIGHTNESS and
red,green,blue files would map to OUTn_COLOR registers.

For banks brightness file would map to BANK_BRIGHTNESS and
red,green,blue files would map to BANK_n_COLOR.

I wouldn't bother with cases when someone connects LEDs of
other colors - he is on his own then.

If you want to have the driver merged quickly then you can
use this interface. We will convert it to LED RGB class once
it is ready. I presume that the interface I outlined will be
supported by one of the brightness-mode's - I like the name
proposed by Vesa.

Effectively - no need to implement HSV algorithm in your driver.

> the LP5024 driver.  Only issue I see is mapping of the LED color to the correct output.  I know what is recommended
> in the data sheet but that does not mean that is what the developers will do.  We cannot always guarantee that
> the red LEDs will be on OUT0, OUT3, OUT6 or on BANK A
> 
> But it is not part of the LED class yet I would have to pull in the patch to enable it.
> 
> What is the thought on this?  Would the HSV/RGB class be pulled in as a part of the LP5024 driver?
> I don't want to put to much effort into code that will have to wait.
> 
> Dan
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-10 21:02                                                           ` Jacek Anaszewski
@ 2019-01-10 21:07                                                             ` Dan Murphy
  0 siblings, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2019-01-10 21:07 UTC (permalink / raw)
  To: Jacek Anaszewski, Pavel Machek
  Cc: Vesa Jääskeläinen, robh+dt, devicetree,
	linux-kernel, linux-leds

On 1/10/19 3:02 PM, Jacek Anaszewski wrote:
> On 1/10/19 8:58 PM, Dan Murphy wrote:
>> On 1/10/19 1:23 PM, Jacek Anaszewski wrote:
>>> Dan,
>>>
>>> On 1/10/19 1:46 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/8/19 3:25 PM, Dan Murphy wrote:
>>>>> Jacek
>>>>>
>>>>> On 1/8/19 3:18 PM, Jacek Anaszewski wrote:
>>>>>> Hi Dan,
>>>>>>
>>>>>> On 1/7/19 10:14 PM, Dan Murphy wrote:
>>>>>>> Jacek
>>>>>>>
>>>>>>> On 1/7/19 2:59 PM, Jacek Anaszewski wrote:
>>>>>>>> Dan,
>>>>>>>>
>>>>>>>> On 1/7/19 8:36 PM, Dan Murphy wrote:
>>>>>>>>> Jacek
>>>>>>>>>
>>>>>>>>> On 1/7/19 1:13 PM, Jacek Anaszewski wrote:
>>>>>>>>>> On 1/6/19 4:52 PM, Jacek Anaszewski wrote:
>>>>>>>>>>> Hi Pavel,
>>>>>>>>>>>
>>>>>>>>>>> On 1/5/19 11:12 PM, Pavel Machek wrote:
>>>>>>>>>>>> Hi!
>>>>>>>>>>>>
>>>>>>>>>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>>>>>>>>>> problems are. It is hard to explain colors over email...
>>>>>>>>>>>>>
>>>>>>>>>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I don't see any problems in exposing separate red,green,blue
>>>>>>>>>>>>> files and brightness for the devices with hardware support for
>>>>>>>>>>>>> that.
>>>>>>>>>>>>
>>>>>>>>>>>> Well, that's what we do today, as three separate LEDs, right?
>>>>>>>>>>>
>>>>>>>>>>> No. It doesn't allow for setting color intensity by having
>>>>>>>>>>> the color fixed beforehand. Below is relevant excerpt from
>>>>>>>>>>> the lp5024 documentation. This is not something that can be
>>>>>>>>>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>>>>>>>>>> reservation that the hardware implementation uses PWM
>>>>>>>>>>> for setting color intensity.
>>>>>>>>>>>
>>>>>>>>>>> <quote>
>>>>>>>>>>> 8.3.1.2 Independent Intensity Control Per RGB LED Module
>>>>>>>>>>>
>>>>>>>>>>> When color is fixed, the independent intensity-control is used to
>>>>>>>>>>> achieve accurate and flexible dimming control for every RGB LED module.
>>>>>>>>>>>
>>>>>>>>>>> 8.3.1.2.1 Intensity-Control Register Configuration
>>>>>>>>>>>
>>>>>>>>>>> Every three consecutive output channels are assigned to their respective
>>>>>>>>>>> intensity-control register (LEDx_BRIGHTNESS). For example, OUT0, OUT1,
>>>>>>>>>>> and OUT2 are assigned to LED0_BRIGHTNESS, so it is recommended to
>>>>>>>>>>> connect the RGB LEDs in the sequence as shown in Table 1. The LP50xx
>>>>>>>>>>> device allows 256-step intensity control for each RGB LED module, which
>>>>>>>>>>> helps achieve a smooth dimming effect.
>>>>>>>>>>> </quote>
>>>>>>>>>>>
>>>>>>>>>>>> I don't have problem with that, either; other drivers already do
>>>>>>>>>>>> that. He's free to use existing same interface.
>>>>>>>>>>>>
>>>>>>>>>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>>>>>>>>>> turning led "white".
>>>>>>>>>>>>
>>>>>>>>>>>> So... perhaps we should agree on requirements, first, and then we can
>>>>>>>>>>>> discuss solutions?
>>>>>>>>>>>>
>>>>>>>>>>>> Requirements for RGB LED interface:
>>>>>>>>>>>>
>>>>>>>>>>>> 1) Userspace should be able to set the white color
>>>>>>>>>>>>
>>>>>>>>>>>> 2) Userspace should be able to arbitrary color from well known list
>>>>>>>>>>>> and it should approximately match what would CRT, LCD or OLED monitor display
>>>>>>>>>>>
>>>>>>>>>>> The difference is that monitor display driver is pre-calibrated
>>>>>>>>>>> for given display by the manufacturer. With the LED controllers the
>>>>>>>>>>> manufacturer has no control over what LEDs will be connected to the
>>>>>>>>>>> iouts. Therefore it should be not surprising that colors produced
>>>>>>>>>>> by custom LEDs are not as user would expect when comparing to
>>>>>>>>>>> the RGB color displayed on the monitor display.
>>>>>>>>>>>
>>>>>>>>>>> TI provides "Various LED Ring Lighting Patterns Reference Design" [0]
>>>>>>>>>>> that show how to produce various patterns with use of the reference
>>>>>>>>>>> board with LED ring built using sixteen 19-337/R6GHBHC-A01/2T LEDs [1].
>>>>>>>>>>>
>>>>>>>>>>> Document [0] mentions also specific "Design considerations" in the
>>>>>>>>>>> chapter 2.2:
>>>>>>>>>>>
>>>>>>>>>>> <quote>
>>>>>>>>>>> Several considerations are taken into account for this particular design:
>>>>>>>>>>> • LED map (ring) for meeting the requirement of popular human-machine interaction style.
>>>>>>>>>>> • LED size, numbers and the diffuse design for meeting lighting pattern uniformity.
>>>>>>>>>>> • Analog dimming in the difference ambient light lux without losing dimming resolution in lighting pattern.
>>>>>>>>>>>
>>>>>>>>>>> These considerations apply to most human-machine interaction end equipment with day and night vision
>>>>>>>>>>> designs in some way, but the designer must decide the particular considerations to take into account for a
>>>>>>>>>>> specific design.
>>>>>>>>>>> </quote>
>>>>>>>>>>>
>>>>>>>>>>> This renders your requirement 2) infeasible with use of custom LEDs
>>>>>>>>>>> any fixed algorithm, since the final effect will always heavily depend
>>>>>>>>>>
>>>>>>>>>> Typo here: s/any fixed/and fixed/
>>>>>>>>>>
>>>>>>>>>>> on the LED circuit design.
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>          2a) LEDs probably slightly change color as they age. That's out of
>>>>>>>>>>>>          scope, unless the variation is much greater than on monitors.
>>>>>>>>>>>>
>>>>>>>>>>>>          2b) Manufacturing differences cause small color variation. Again,
>>>>>>>>>>>>          that's out of scope, unless the variation is much greater than on
>>>>>>>>>>>>          monitors.
>>>>>>>>>>>>
>>>>>>>>>>>> Nice to have features:
>>>>>>>>>>>>
>>>>>>>>>>>> 3) Full range of available colors/intensities should be available to
>>>>>>>>>>>> userspace
>>>>>>>>>>>>
>>>>>>>>>>>> 4) Interface should work well with existing triggers
>>>>>>>>>>>>
>>>>>>>>>>>> 5) It would be nice if userland knew how many lumens are produced at
>>>>>>>>>>>> each wavelength for each setting (again, minus aging and manufacturing
>>>>>>>>>>>> variations).
>>>>>>>>>>>>
>>>>>>>>>>>> 6) Complexity of math in kernel should be low, and preferably it
>>>>>>>>>>>> should be integer or fixed point
>>>>>>>>>>>>
>>>>>>>>>>>> Problems:
>>>>>>>>>>>>
>>>>>>>>>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>>>>>>>>>> red/green/blue channels will result in nothing close to white
>>>>>>>>>>>> light. In fact, to get white light on N900, blue and green channel's
>>>>>>>>>>>> PWM needs to be set pretty low, as in 5%.
>>>>>>>>>>>>
>>>>>>>>>>>> b) LED class does not define any relation between "brightness" in
>>>>>>>>>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>>>>>>>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>>>>>>>>>> of lumens. RGB color model uses even more complex function.
>>>>>>>>>>>>
>>>>>>>>>>>> c) Except for white LEDs, LEDs are basically sources of single
>>>>>>>>>>>> wavelength of light, while CRTs and LCDs produce broader
>>>>>>>>>>>> spectrums.
>>>>>>>>>>>>
>>>>>>>>>>>> d) RG, RGBW and probably other LED combinations exist.
>>>>>>>>>>>>
>>>>>>>>>>>> e) Not all "red" LEDs will produce same wavelength. Similar
>>>>>>>>>>>> differences will exist for other colors.
>>>>>>>>>>>>
>>>>>>>>>>>> f) We have existing RGB LEDs represented as three separate
>>>>>>>>>>>> monochromatic LEDs in sysfs.
>>>>>>>>>>>
>>>>>>>>>>> One general question: do you have any solutions in store?
>>>>>>>>>>>
>>>>>>>>>>> [0] http://www.ti.com/lit/ug/tiduee6/tiduee6.pdf
>>>>>>>>>>> [1] http://www.everlight.com/file/ProductFile/19-337-R6GHBHC-A01-2T.pdf
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I just wanted to point out that there are 4 total devices right now that use the same mapping
>>>>>>>>>
>>>>>>>>> LP5018, LP5024, LP5030 and the LP5036.
>>>>>>>>>
>>>>>>>>> I can implement what ever we would like to I just need to know what to design against.
>>>>>>>>
>>>>>>>> As you can see from the discussion in this thread it may take some
>>>>>>>> time to work out the interface satisfying everyone. I made some design
>>>>>>>> proposal, but Pavel had no warm word for it. It would be easier if
>>>>>>>> we had more opinions.
>>>>>>>
>>>>>>> I got it from the threads and just the time invested in the FW and HSV.
>>>>>>>
>>>>>>>>
>>>>>>>> How do you feel about using brightness file for setting LEDn_BRIGHTNESS?
>>>>>>>
>>>>>>> I am using that now.  The brightness file will adjust the overall brightness of the LED group
>>>>>>> or bank pending on how the LEDs are grouped in the DT file.
>>>>>>>
>>>>>>>>
>>>>>>>> Does increasing LEDn_BRIGHTNESS value (i.e. color intensity) feel like
>>>>>>>> increasing color lightness (i.e. the pattern presented in the video [0]
>>>>>>>> starting from 1:22)?
>>>>>>>
>>>>>>> No unfortunately this is why I introduced the new files to control the individual RGB intensities
>>>>>>> so that the designers can set, tune, create color variations or patterns like the video.
>>>>>>>
>>>>>>> The RGB group brightness would be independent based on lighting conditions, enclosures and diffusers.
>>>>>>> So you could technically be changing color and overall brightness virtually simultaneously
>>>>>>
>>>>>> Oh, so this is surprising. Now it gets even more obscure to me.
>>>>>>
>>>>>> It would be really helpful if we could see a video showing
>>>>>> the LED effects with regard to the applied settings.
>>>>>
>>>>> Well I am doing a test off the command line to ensure the user space can interface with the RGB LED.
>>>>>
>>>>> I can ping someone in product development to see the application of this device if that would help.
>>>>> We did give them a test driver to work on their features but told them the driver is not final until it
>>>>> is in the mainline kernel
>>>>>
>>>>> Dan
>>>>>
>>>>>>
>>>>>>>>> But keep in mind I still need to invest my time in the other TI-lmu patches on my list to complete.
>>>>>>>>
>>>>>>>> Do what you deem most suitable for you. We are here only to help
>>>>>>>> merging the patches, but keeping in mind that kernel interface once
>>>>>>>> introduced must be preserved forever. Therefore we need to do our
>>>>>>>> best to make the best possible design decisions.
>>>>>>>>
>>>>>>>> [0] https://www.youtube.com/watch?v=qdt-alh8i6E
>>>>>>>>
>>>>>>>
>>>>>>> I understand.  Maybe I can make the files generic to use for either control or individual control.
>>>>>>>
>>>>>>> We can probably define new ABI's until either HSV or DT frameworks get going.  And them make the file presentation
>>>>>>> configurable and default to the new files.
>>>>>>
>>>>>> I am leaning towards it. Just commented on your patches.
>>>>>>
>>>>>
>>>>>
>>>>
>>>> Asked the HW team for videos this is what they sent
>>>> https://training.ti.com/lp50x-led-drivers-achieve-optimal-color-brightness-zero-audible-noise
>>>> https://training.ti.com/how-configuring-led-brightness-color-and-patterns-lp50x-gui-tool
>>>>
>>>> Not sure how helpful these would be
>>>
>>> Thank you for the videos - they are helpful, and they confirm my first
>>> impression regarding the LEDn_BRIGHTNESS effect. In is shown in the
>>> second video starting from 3:37.
>>>
>>> This is the same what I was asking about previously (video [0] from
>>> previous message starting from 1:22). For me this looks similarly
>>> to increasing V of HSV or L of HSL [1].
>>>
>>> You denied, so either we interpret colors differently, or there was
>>> some misunderstanding.
>>>
>>> [1] http://hslpicker.com
>>>
>>
>> Well I did indicate later that I could work on implementing against the HSV/RGB framework and fit that into
> 
> I just wanted to make sure that brightness file semantics fits
> for this particular LEDn_BRIGHTNESS feature.
> Now it is clear to me - yes it does.
> 
> For RGB LED modules brightness file would map to LEDn_BRIGHTNESS and
> red,green,blue files would map to OUTn_COLOR registers.
> 
> For banks brightness file would map to BANK_BRIGHTNESS and
> red,green,blue files would map to BANK_n_COLOR.
> 
> I wouldn't bother with cases when someone connects LEDs of
> other colors - he is on his own then.
> 
> If you want to have the driver merged quickly then you can
> use this interface. We will convert it to LED RGB class once
> it is ready. I presume that the interface I outlined will be
> supported by one of the brightness-mode's - I like the name
> proposed by Vesa.
> 
> Effectively - no need to implement HSV algorithm in your driver.
> 

Not quickly merged.  I would prefer it to be correct.

So you are saying I need to present brightness, red, blue and green files to the user space?

That would work for me.

There were a few proposals in a very lengthy chain so I want to be clear on the interfaces.

Dan

>> the LP5024 driver.  Only issue I see is mapping of the LED color to the correct output.  I know what is recommended
>> in the data sheet but that does not mean that is what the developers will do.  We cannot always guarantee that
>> the red LEDs will be on OUT0, OUT3, OUT6 or on BANK A
>>
>> But it is not part of the LED class yet I would have to pull in the patch to enable it.
>>
>> What is the thought on this?  Would the HSV/RGB class be pulled in as a part of the LP5024 driver?
>> I don't want to put to much effort into code that will have to wait.
>>
>> Dan
>>
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-10 20:43                         ` Dan Murphy
@ 2019-01-10 22:03                           ` Jacek Anaszewski
  2019-01-10 23:51                             ` Dan Murphy
  2019-01-11 12:38                             ` Dan Murphy
  0 siblings, 2 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-10 22:03 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

On 1/10/19 9:43 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>> Dan,
>>
>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>> Hi Dan,
>>>>
>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>> Jacek
>>>>>
>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>> Hi Dan,
>>>>>>>>
>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>> Jacek
>>>>>>>>>>>
>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>> Dan,
>>>>>>>>>>>>
>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>
>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>> ---
>>>>>>>>>>>>>         .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>         1 file changed, 63 insertions(+)
>>>>>>>>>>>>>         create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>
>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>> +    };
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>
>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> That will work too.
>>>>>>>>>>
>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>
>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>
>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>
>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>> triplets somehow then?
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>
>>>>>>>> led-sources should map to iouts directly.
>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>
>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>> and so on.
>>>>>>>
>>>>>>>>
>>>>>>>> for banks:
>>>>>>>>
>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>
>>>>>>>
>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>
>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>
>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>> registers.
>>>>>>
>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>> for such purposes.
>>>>>>
>>>>>
>>>>> Yes Pavel also mentioned that as well.
>>>>>
>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>
>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>> module or to a bank. Basing on that I created my DT example above.
>>>>
>>>
>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>> out 0, 3 are mapped to BANK A
>>> out 1, 4 are mapped to BANK B
>>
>> Just noticed that I made a mistake in my example, it should have been:
>>
>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>
>>> out 2, 5 are mapped to BANK C
>>
>> Correct.
>>
>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>
>> That's right.
>>
>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>> led-sources = < 0 1 2 3 4 5 >;
>>
>> Why? This would be a mix of three banks. Like you listed above.
>> I'm still interpreting led-sources elements as iout identifiers.
>>
> 
> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.

There is naming conflict I noticed just now - LEDn_BANK_EN bits
in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).

> These OUTPUTs will appear as a single RGB LED grouping.

Single? W would rather expect that we get two RGB LED modules, whose
brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
registers respectively.

>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>
>>> non-banked case would be
>>> led-sources = < 0 1 2 >;
>>
>> Agreed here. It would be LED0 RGB LED module.
>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>> are inherently mapped to the bank.
>>
>> To three separate banks, right?
>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
> 
> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
> color adjustment registers.

Here as above, I would expect two separate banks - LED0 and LED1.
Moreover - not 3 color adjustment registers, but six - one per iout:
OUT0_COLOR to OUT5_COLOR.

>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>
>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>> LED file presented to the user space.
>>
>> I suspect there is logical clash here due to interpreting
>> led-sources elements as iouts in one case and LEDn modules
>> in the other case.
>>
> 
> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.

We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
banks (A,B,C), which are enabled by default, am I right?

Bank A iouts: 0, 3 ,6, 9, 12, 15
Bank B iouts: 1, 4, 7, 10, 13, 16
Bank C iouts: 2, 5, 8, 11, 14, 17

When RGB LED module is enabled (via LEDn_Bank_EN bit),
the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
related OUTn_COLOR registers. Is it correct?

> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.

Ekhm, I messed something here.

So for this I would define a single LED class device.
Related DT node would not need led-sources at all,
but only ti,control-bank. The semantics would be:
controls all iouts not taken by RGB LED modules.

I would also add Table 1 contents (Bank Number and LED Number
Assignment) to the DT bindings.

> If you define LED0 and LED1 as banked then OUT0->5 are banked and it would be considered a single virtual output.
> 
> LED_CONFIG0 even uses the modular approach to define what is banked and what is not.  With the modular approach to led-sources
> the mapping of the sources to the CONFIG register become 1-1.
> 
> 1 = LED7 bank control mode enabled
> 0 = LED7 independent control mode enabled
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-10 22:03                           ` Jacek Anaszewski
@ 2019-01-10 23:51                             ` Dan Murphy
  2019-01-11 12:38                             ` Dan Murphy
  1 sibling, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2019-01-10 23:51 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/10/19 4:03 PM, Jacek Anaszewski wrote:
> On 1/10/19 9:43 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>>> Dan,
>>>
>>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>>> Hi Dan,
>>>>>
>>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>>> Jacek
>>>>>>
>>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>>> Hi Dan,
>>>>>>>>>
>>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>>> Jacek
>>>>>>>>>>>>
>>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>> Dan,
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>         .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>>         1 file changed, 63 insertions(+)
>>>>>>>>>>>>>>         create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>>> +    };
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>>
>>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> That will work too.
>>>>>>>>>>>
>>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>>
>>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>>
>>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>>
>>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>>> triplets somehow then?
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>>
>>>>>>>>> led-sources should map to iouts directly.
>>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>>
>>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>>> and so on.
>>>>>>>>
>>>>>>>>>
>>>>>>>>> for banks:
>>>>>>>>>
>>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>>
>>>>>>>>
>>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>>
>>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>>
>>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>>> registers.
>>>>>>>
>>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>>> for such purposes.
>>>>>>>
>>>>>>
>>>>>> Yes Pavel also mentioned that as well.
>>>>>>
>>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>>
>>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>>> module or to a bank. Basing on that I created my DT example above.
>>>>>
>>>>
>>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>>> out 0, 3 are mapped to BANK A
>>>> out 1, 4 are mapped to BANK B
>>>
>>> Just noticed that I made a mistake in my example, it should have been:
>>>
>>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>>
>>>> out 2, 5 are mapped to BANK C
>>>
>>> Correct.
>>>
>>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>>
>>> That's right.
>>>
>>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>>> led-sources = < 0 1 2 3 4 5 >;
>>>
>>> Why? This would be a mix of three banks. Like you listed above.
>>> I'm still interpreting led-sources elements as iout identifiers.
>>>
>>
>> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
>> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.
> 
> There is naming conflict I noticed just now - LEDn_BANK_EN bits
> in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).
> 

I read this a couple times but not sure I understand your comments.  The bits in the LED_CONFIG0 enable the bank control for the
LED modules.

Are you saying the conflict is in the data sheet?  the code? or an understanding?

>> These OUTPUTs will appear as a single RGB LED grouping.
> 
> Single? W would rather expect that we get two RGB LED modules, whose
> brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
> registers respectively.

When you set bank control on a certain LED module all the outputs under that module are controlled by the bank registers.
So if you say LED0 and LED6 are bank controlled then the RGB LED clusters connected to output 0, 1, 2, 15, 16 and 17 will all
be controlled by the bank register and react simultaneously to mixing or brightness controls,  LED0_BRIGHTNESS and LED6_BRIGHTNESS
register and mixer controls will have no affect on the individaul LED clusters connect to the outputs.

Dan

> 
>>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>>
>>>> non-banked case would be
>>>> led-sources = < 0 1 2 >;
>>>
>>> Agreed here. It would be LED0 RGB LED module.
>>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>>> are inherently mapped to the bank.
>>>
>>> To three separate banks, right?
>>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
>>
>> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
>> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
>> color adjustment registers.
> 
> Here as above, I would expect two separate banks - LED0 and LED1.
> Moreover - not 3 color adjustment registers, but six - one per iout:
> OUT0_COLOR to OUT5_COLOR.
> 
>>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>>
>>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>>> LED file presented to the user space.
>>>
>>> I suspect there is logical clash here due to interpreting
>>> led-sources elements as iouts in one case and LEDn modules
>>> in the other case.
>>>
>>
>> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
> 
> We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
> banks (A,B,C), which are enabled by default, am I right?
> 
> Bank A iouts: 0, 3 ,6, 9, 12, 15
> Bank B iouts: 1, 4, 7, 10, 13, 16
> Bank C iouts: 2, 5, 8, 11, 14, 17
> 
> When RGB LED module is enabled (via LEDn_Bank_EN bit),
> the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
> lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
> related OUTn_COLOR registers. Is it correct?
> 
>> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
>> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.
> 
> Ekhm, I messed something here.
> 
> So for this I would define a single LED class device.
> Related DT node would not need led-sources at all,
> but only ti,control-bank. The semantics would be:
> controls all iouts not taken by RGB LED modules.
> 
> I would also add Table 1 contents (Bank Number and LED Number
> Assignment) to the DT bindings.
> 
>> If you define LED0 and LED1 as banked then OUT0->5 are banked and it would be considered a single virtual output.
>>
>> LED_CONFIG0 even uses the modular approach to define what is banked and what is not.  With the modular approach to led-sources
>> the mapping of the sources to the CONFIG register become 1-1.
>>
>> 1 = LED7 bank control mode enabled
>> 0 = LED7 independent control mode enabled
>>
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-10 22:03                           ` Jacek Anaszewski
  2019-01-10 23:51                             ` Dan Murphy
@ 2019-01-11 12:38                             ` Dan Murphy
  2019-01-11 21:52                               ` Jacek Anaszewski
  1 sibling, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-11 12:38 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

Sorry I missed some replies

On 1/10/19 4:03 PM, Jacek Anaszewski wrote:
> On 1/10/19 9:43 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>>> Dan,
>>>
>>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>>> Hi Dan,
>>>>>
>>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>>> Jacek
>>>>>>
>>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>>> Hi Dan,
>>>>>>>>>
>>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>>> Jacek
>>>>>>>>>>>>
>>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>> Dan,
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>         .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>>         1 file changed, 63 insertions(+)
>>>>>>>>>>>>>>         create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>>> +    };
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>>
>>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> That will work too.
>>>>>>>>>>>
>>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>>
>>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>>
>>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>>
>>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>>> triplets somehow then?
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>>
>>>>>>>>> led-sources should map to iouts directly.
>>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>>
>>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>>> and so on.
>>>>>>>>
>>>>>>>>>
>>>>>>>>> for banks:
>>>>>>>>>
>>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>>
>>>>>>>>
>>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>>
>>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>>
>>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>>> registers.
>>>>>>>
>>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>>> for such purposes.
>>>>>>>
>>>>>>
>>>>>> Yes Pavel also mentioned that as well.
>>>>>>
>>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>>
>>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>>> module or to a bank. Basing on that I created my DT example above.
>>>>>
>>>>
>>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>>> out 0, 3 are mapped to BANK A
>>>> out 1, 4 are mapped to BANK B
>>>
>>> Just noticed that I made a mistake in my example, it should have been:
>>>
>>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>>
>>>> out 2, 5 are mapped to BANK C
>>>
>>> Correct.
>>>
>>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>>
>>> That's right.
>>>
>>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>>> led-sources = < 0 1 2 3 4 5 >;
>>>
>>> Why? This would be a mix of three banks. Like you listed above.
>>> I'm still interpreting led-sources elements as iout identifiers.
>>>
>>
>> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
>> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.
> 
> There is naming conflict I noticed just now - LEDn_BANK_EN bits
> in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).
> 
>> These OUTPUTs will appear as a single RGB LED grouping.
> 
> Single? W would rather expect that we get two RGB LED modules, whose
> brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
> registers respectively.
> 
>>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>>
>>>> non-banked case would be
>>>> led-sources = < 0 1 2 >;
>>>
>>> Agreed here. It would be LED0 RGB LED module.
>>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>>> are inherently mapped to the bank.
>>>
>>> To three separate banks, right?
>>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
>>
>> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
>> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
>> color adjustment registers.
> 
> Here as above, I would expect two separate banks - LED0 and LED1.
> Moreover - not 3 color adjustment registers, but six - one per iout:
> OUT0_COLOR to OUT5_COLOR.
> 

When the LEDs are banked the banked LEDs are controlled by the bank registers not the LEDx registers
so you should only see 3 color adjustments on the banked LEDs.

>>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>>
>>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>>> LED file presented to the user space.
>>>
>>> I suspect there is logical clash here due to interpreting
>>> led-sources elements as iouts in one case and LEDn modules
>>> in the other case.
>>>
>>
>> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
> 
> We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
> banks (A,B,C), which are enabled by default, am I right?

No.  Independent LED modules are enabled by default.  You have to explicitly enable the banks.

> 
> Bank A iouts: 0, 3 ,6, 9, 12, 15
> Bank B iouts: 1, 4, 7, 10, 13, 16
> Bank C iouts: 2, 5, 8, 11, 14, 17
> 
> When RGB LED module is enabled (via LEDn_Bank_EN bit),
> the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
> lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
> related OUTn_COLOR registers. Is it correct?

No it is the opposite.  When the bit is enabled LED banking is enabled and the BANK brightness and color registers over
ride the LEDx color and brightness registers.

Default is independent control of the RGB via the LEDx color and brightness registers.

> 
>> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
>> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.
> 
> Ekhm, I messed something here.
> 
> So for this I would define a single LED class device.
> Related DT node would not need led-sources at all,
> but only ti,control-bank. The semantics would be:
> controls all iouts not taken by RGB LED modules.
> 

Hmm.  I guess I will put that on hold until you read the responses.  I am not sure that would work or
that would be really clean.  I still believe that mapping led-sources to the LEDx module number is the cleanest
simplest solution since the driver cannot inter mix different outputs for enablement.

> I would also add Table 1 contents (Bank Number and LED Number
> Assignment) to the DT bindings.
> 

Should I add that to the DT binding or reference the data sheet table since this driver will support 4 different devices
with varying number of outputs from 18-36.

Dan

>> If you define LED0 and LED1 as banked then OUT0->5 are banked and it would be considered a single virtual output.
>>
>> LED_CONFIG0 even uses the modular approach to define what is banked and what is not.  With the modular approach to led-sources
>> the mapping of the sources to the CONFIG register become 1-1.
>>
>> 1 = LED7 bank control mode enabled
>> 0 = LED7 independent control mode enabled
>>
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-11 12:38                             ` Dan Murphy
@ 2019-01-11 21:52                               ` Jacek Anaszewski
  2019-01-12 17:09                                 ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-11 21:52 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Dan,

On 1/11/19 1:38 PM, Dan Murphy wrote:
> Jacek
> 
> Sorry I missed some replies
> 
> On 1/10/19 4:03 PM, Jacek Anaszewski wrote:
>> On 1/10/19 9:43 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>>>> Dan,
>>>>
>>>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>>>> Jacek
>>>>>
>>>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>>>> Hi Dan,
>>>>>>
>>>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>>>> Jacek
>>>>>>>
>>>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>>>> Hi Dan,
>>>>>>>>>>
>>>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>>>> Jacek
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>> Dan,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>          .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>>>          1 file changed, 63 insertions(+)
>>>>>>>>>>>>>>>          create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>>>> +    };
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> That will work too.
>>>>>>>>>>>>
>>>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>>>
>>>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>>>
>>>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>>>
>>>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>>>> triplets somehow then?
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>>>
>>>>>>>>>> led-sources should map to iouts directly.
>>>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>>>
>>>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>>>> and so on.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> for banks:
>>>>>>>>>>
>>>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>>>
>>>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>>>
>>>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>>>> registers.
>>>>>>>>
>>>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>>>> for such purposes.
>>>>>>>>
>>>>>>>
>>>>>>> Yes Pavel also mentioned that as well.
>>>>>>>
>>>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>>>
>>>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>>>> module or to a bank. Basing on that I created my DT example above.
>>>>>>
>>>>>
>>>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>>>> out 0, 3 are mapped to BANK A
>>>>> out 1, 4 are mapped to BANK B
>>>>
>>>> Just noticed that I made a mistake in my example, it should have been:
>>>>
>>>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>>>
>>>>> out 2, 5 are mapped to BANK C
>>>>
>>>> Correct.
>>>>
>>>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>>>
>>>> That's right.
>>>>
>>>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>>>> led-sources = < 0 1 2 3 4 5 >;
>>>>
>>>> Why? This would be a mix of three banks. Like you listed above.
>>>> I'm still interpreting led-sources elements as iout identifiers.
>>>>
>>>
>>> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
>>> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.
>>
>> There is naming conflict I noticed just now - LEDn_BANK_EN bits
>> in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).
>>
>>> These OUTPUTs will appear as a single RGB LED grouping.
>>
>> Single? W would rather expect that we get two RGB LED modules, whose
>> brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
>> registers respectively.
>>
>>>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>>>
>>>>> non-banked case would be
>>>>> led-sources = < 0 1 2 >;
>>>>
>>>> Agreed here. It would be LED0 RGB LED module.
>>>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>>>> are inherently mapped to the bank.
>>>>
>>>> To three separate banks, right?
>>>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
>>>
>>> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
>>> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
>>> color adjustment registers.
>>
>> Here as above, I would expect two separate banks - LED0 and LED1.
>> Moreover - not 3 color adjustment registers, but six - one per iout:
>> OUT0_COLOR to OUT5_COLOR.
>>
> 
> When the LEDs are banked the banked LEDs are controlled by the bank registers not the LEDx registers
> so you should only see 3 color adjustments on the banked LEDs.
> 
>>>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>>>
>>>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>>>> LED file presented to the user space.
>>>>
>>>> I suspect there is logical clash here due to interpreting
>>>> led-sources elements as iouts in one case and LEDn modules
>>>> in the other case.
>>>>
>>>
>>> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
>>
>> We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
>> banks (A,B,C), which are enabled by default, am I right?
> 
> No.  Independent LED modules are enabled by default.  You have to explicitly enable the banks.
> 
>>
>> Bank A iouts: 0, 3 ,6, 9, 12, 15
>> Bank B iouts: 1, 4, 7, 10, 13, 16
>> Bank C iouts: 2, 5, 8, 11, 14, 17
>>
>> When RGB LED module is enabled (via LEDn_Bank_EN bit),
>> the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
>> lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
>> related OUTn_COLOR registers. Is it correct?
> 
> No it is the opposite.  When the bit is enabled LED banking is enabled and the BANK brightness and color registers over
> ride the LEDx color and brightness registers.
> 
> Default is independent control of the RGB via the LEDx color and brightness registers.
> 
>>
>>> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
>>> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.
>>
>> Ekhm, I messed something here.
>>
>> So for this I would define a single LED class device.
>> Related DT node would not need led-sources at all,
>> but only ti,control-bank. The semantics would be:
>> controls all iouts not taken by RGB LED modules.
>>
> 
> Hmm.  I guess I will put that on hold until you read the responses.  I am not sure that would work or
> that would be really clean.  I still believe that mapping led-sources to the LEDx module number is the cleanest
> simplest solution since the driver cannot inter mix different outputs for enablement.

I've read the doc again more carefully and hopefully I finally have
proper understanding. Let's check it.

1. On reset LED_CONFIG0 bits are zeroed, which means
    LEDn module independent control mode.
2. LEDn modules (i.e. IOUT triplets) are controlled independently,
    with use of LEDn_BRIGHTNESS registers, and each IOUT color can
    be adjusted using OUTn_CONTROL registers.
3. LEDn_Bank_EN bits, when set to 1, assign given RGB LED module
    to one global bank, controlled via BANK_BRIGHTNESS and BANK_n_COLOR
    registers.

Having that, I'd see led-sources definitions as follows
(led-sources element is IOUT identifier)

1.

- LED0, LED1, LED2, LED3 modules controlled by separate
   LED class devices

led-sources = <0 1 2>   // LED0
led-sources = <3 4 5>   // LED1
led-sources = <6 7 8>   // LED2
led-sources = <9 10 11> // LED3

2.

- LED0 and LED3 modules assigned to the bank, and controlled
   by one LED class device,
- LED1 and LED2 modules controlled by separate LED class devices

led-sources = <0 1 2 9 10 11> // Bank with LED0 and LED3
led-sources = <3 4 5>         // LED1
led-sources = <6 7 8>         // LED2


So now I see your point. It would be indeed easier
to switch to LEDn module identifiers for led-sources
elements. With that the definitions would look like
this:


1.

- LED0, LED1, LED2, LED3 modules controlled by separate
   LED class devices

led-sources = <0>   // LED0
led-sources = <1>   // LED1
led-sources = <2>   // LED2
led-sources = <3>   // LED3

2.

- LED0 and LED3 modules assigned to the bank, and controlled
   by one LED class device,
- LED1 and LED2 modules controlled by separate LED class devices

led-sources = <0 3> // Bank with LED0 and LED3
led-sources = <1>   // LED1
led-sources = <2>   // LED2


But, I don't think use of led-sources is justified in
this case. I propose to introduce device specific properties:

ti,led-module and ti,led-bank

With that we would have:

ti,led-bank = <0 3>   // Bank with LED0 and LED3 modules
ti,led-module = <1>   // LED1
ti.led-module = <2>   // LED2


>> I would also add Table 1 contents (Bank Number and LED Number
>> Assignment) to the DT bindings.
>>
> 
> Should I add that to the DT binding or reference the data sheet table since this driver will support 4 different devices
> with varying number of outputs from 18-36.

My first thought was to show full table, but four different
mappings would add too much noise. So the reference to the data
sheet should suffice.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-11 21:52                               ` Jacek Anaszewski
@ 2019-01-12 17:09                                 ` Dan Murphy
  2019-01-12 19:48                                   ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-12 17:09 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/11/19 3:52 PM, Jacek Anaszewski wrote:
> Dan,
> 
> On 1/11/19 1:38 PM, Dan Murphy wrote:
>> Jacek
>>
>> Sorry I missed some replies
>>
>> On 1/10/19 4:03 PM, Jacek Anaszewski wrote:
>>> On 1/10/19 9:43 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>>>>> Dan,
>>>>>
>>>>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>>>>> Jacek
>>>>>>
>>>>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>>>>> Hi Dan,
>>>>>>>
>>>>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>>>>> Jacek
>>>>>>>>
>>>>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>>>>> Hi Dan,
>>>>>>>>>>>
>>>>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>>>>> Jacek
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>> Dan,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>          .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>>>>          1 file changed, 63 insertions(+)
>>>>>>>>>>>>>>>>          create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>>>>> +    };
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> That will work too.
>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>>>>
>>>>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>>>>> triplets somehow then?
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>>>>
>>>>>>>>>>> led-sources should map to iouts directly.
>>>>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>>>>
>>>>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>>>>> and so on.
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> for banks:
>>>>>>>>>>>
>>>>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>>>>
>>>>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>>>>
>>>>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>>>>> registers.
>>>>>>>>>
>>>>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>>>>> for such purposes.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yes Pavel also mentioned that as well.
>>>>>>>>
>>>>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>>>>
>>>>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>>>>> module or to a bank. Basing on that I created my DT example above.
>>>>>>>
>>>>>>
>>>>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>>>>> out 0, 3 are mapped to BANK A
>>>>>> out 1, 4 are mapped to BANK B
>>>>>
>>>>> Just noticed that I made a mistake in my example, it should have been:
>>>>>
>>>>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>>>>
>>>>>> out 2, 5 are mapped to BANK C
>>>>>
>>>>> Correct.
>>>>>
>>>>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>>>>
>>>>> That's right.
>>>>>
>>>>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>>>>> led-sources = < 0 1 2 3 4 5 >;
>>>>>
>>>>> Why? This would be a mix of three banks. Like you listed above.
>>>>> I'm still interpreting led-sources elements as iout identifiers.
>>>>>
>>>>
>>>> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
>>>> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.
>>>
>>> There is naming conflict I noticed just now - LEDn_BANK_EN bits
>>> in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).
>>>
>>>> These OUTPUTs will appear as a single RGB LED grouping.
>>>
>>> Single? W would rather expect that we get two RGB LED modules, whose
>>> brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
>>> registers respectively.
>>>
>>>>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>>>>
>>>>>> non-banked case would be
>>>>>> led-sources = < 0 1 2 >;
>>>>>
>>>>> Agreed here. It would be LED0 RGB LED module.
>>>>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>>>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>>>>> are inherently mapped to the bank.
>>>>>
>>>>> To three separate banks, right?
>>>>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
>>>>
>>>> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
>>>> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
>>>> color adjustment registers.
>>>
>>> Here as above, I would expect two separate banks - LED0 and LED1.
>>> Moreover - not 3 color adjustment registers, but six - one per iout:
>>> OUT0_COLOR to OUT5_COLOR.
>>>
>>
>> When the LEDs are banked the banked LEDs are controlled by the bank registers not the LEDx registers
>> so you should only see 3 color adjustments on the banked LEDs.
>>
>>>>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>>>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>>>>
>>>>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>>>>> LED file presented to the user space.
>>>>>
>>>>> I suspect there is logical clash here due to interpreting
>>>>> led-sources elements as iouts in one case and LEDn modules
>>>>> in the other case.
>>>>>
>>>>
>>>> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
>>>
>>> We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
>>> banks (A,B,C), which are enabled by default, am I right?
>>
>> No.  Independent LED modules are enabled by default.  You have to explicitly enable the banks.
>>
>>>
>>> Bank A iouts: 0, 3 ,6, 9, 12, 15
>>> Bank B iouts: 1, 4, 7, 10, 13, 16
>>> Bank C iouts: 2, 5, 8, 11, 14, 17
>>>
>>> When RGB LED module is enabled (via LEDn_Bank_EN bit),
>>> the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
>>> lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
>>> related OUTn_COLOR registers. Is it correct?
>>
>> No it is the opposite.  When the bit is enabled LED banking is enabled and the BANK brightness and color registers over
>> ride the LEDx color and brightness registers.
>>
>> Default is independent control of the RGB via the LEDx color and brightness registers.
>>
>>>
>>>> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
>>>> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.
>>>
>>> Ekhm, I messed something here.
>>>
>>> So for this I would define a single LED class device.
>>> Related DT node would not need led-sources at all,
>>> but only ti,control-bank. The semantics would be:
>>> controls all iouts not taken by RGB LED modules.
>>>
>>
>> Hmm.  I guess I will put that on hold until you read the responses.  I am not sure that would work or
>> that would be really clean.  I still believe that mapping led-sources to the LEDx module number is the cleanest
>> simplest solution since the driver cannot inter mix different outputs for enablement.
> 
> I've read the doc again more carefully and hopefully I finally have
> proper understanding. Let's check it.
> 
> 1. On reset LED_CONFIG0 bits are zeroed, which means
>    LEDn module independent control mode.
> 2. LEDn modules (i.e. IOUT triplets) are controlled independently,
>    with use of LEDn_BRIGHTNESS registers, and each IOUT color can
>    be adjusted using OUTn_CONTROL registers.
> 3. LEDn_Bank_EN bits, when set to 1, assign given RGB LED module
>    to one global bank, controlled via BANK_BRIGHTNESS and BANK_n_COLOR
>    registers.
> 
> Having that, I'd see led-sources definitions as follows
> (led-sources element is IOUT identifier)
> 
> 1.
> 
> - LED0, LED1, LED2, LED3 modules controlled by separate
>   LED class devices
> 
> led-sources = <0 1 2>   // LED0
> led-sources = <3 4 5>   // LED1
> led-sources = <6 7 8>   // LED2
> led-sources = <9 10 11> // LED3
> 
> 2.
> 
> - LED0 and LED3 modules assigned to the bank, and controlled
>   by one LED class device,
> - LED1 and LED2 modules controlled by separate LED class devices
> 
> led-sources = <0 1 2 9 10 11> // Bank with LED0 and LED3
> led-sources = <3 4 5>         // LED1
> led-sources = <6 7 8>         // LED2
> 
> 
> So now I see your point. It would be indeed easier
> to switch to LEDn module identifiers for led-sources
> elements. With that the definitions would look like
> this:
> 
> 
> 1.
> 
> - LED0, LED1, LED2, LED3 modules controlled by separate
>   LED class devices
> 
> led-sources = <0>   // LED0
> led-sources = <1>   // LED1
> led-sources = <2>   // LED2
> led-sources = <3>   // LED3
> 
> 2.
> 
> - LED0 and LED3 modules assigned to the bank, and controlled
>   by one LED class device,
> - LED1 and LED2 modules controlled by separate LED class devices
> 
> led-sources = <0 3> // Bank with LED0 and LED3
> led-sources = <1>   // LED1
> led-sources = <2>   // LED2
> 

This is exactly how I submitted the code.

> 
> But, I don't think use of led-sources is justified in
> this case. I propose to introduce device specific properties:
> 
> ti,led-module and ti,led-bank
> 
> With that we would have:
> 
> ti,led-bank = <0 3>   // Bank with LED0 and LED3 modules
> ti,led-module = <1>   // LED1
> ti.led-module = <2>   // LED2
> 

We are now aligned.  I can change the led-sources to the TI specific if there are no further objections.
In doing this I can eliminate the ti,control-bank property.

> 
>>> I would also add Table 1 contents (Bank Number and LED Number
>>> Assignment) to the DT bindings.
>>>
>>
>> Should I add that to the DT binding or reference the data sheet table since this driver will support 4 different devices
>> with varying number of outputs from 18-36.
> 
> My first thought was to show full table, but four different
> mappings would add too much noise. So the reference to the data
> sheet should suffice.
> 

OK

One last question I am going to add the LP5036 and 30 which have the same technology but slightly different register maps.
Should I rename the driver to LP5036.c as the 30, 24 and 18 would technically be subsets?



Dan

-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-12 17:09                                 ` Dan Murphy
@ 2019-01-12 19:48                                   ` Jacek Anaszewski
  2019-01-14 12:27                                     ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-12 19:48 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Hi Dan,

On 1/12/19 6:09 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/11/19 3:52 PM, Jacek Anaszewski wrote:
>> Dan,
>>
>> On 1/11/19 1:38 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> Sorry I missed some replies
>>>
>>> On 1/10/19 4:03 PM, Jacek Anaszewski wrote:
>>>> On 1/10/19 9:43 PM, Dan Murphy wrote:
>>>>> Jacek
>>>>>
>>>>> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>>>>>> Dan,
>>>>>>
>>>>>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>>>>>> Jacek
>>>>>>>
>>>>>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>>>>>> Hi Dan,
>>>>>>>>
>>>>>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>>>>>> Jacek
>>>>>>>>>
>>>>>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>> Hi Dan,
>>>>>>>>>>>>
>>>>>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>> Jacek
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>>> Dan,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>           .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>>>>>           1 file changed, 63 insertions(+)
>>>>>>>>>>>>>>>>>           create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>>>>>> +    };
>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> That will work too.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>>>>>> triplets somehow then?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>>>>>
>>>>>>>>>>>> led-sources should map to iouts directly.
>>>>>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>>>>>
>>>>>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>>>>>> and so on.
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> for banks:
>>>>>>>>>>>>
>>>>>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>>>>>
>>>>>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>>>>>
>>>>>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>>>>>> registers.
>>>>>>>>>>
>>>>>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>>>>>> for such purposes.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes Pavel also mentioned that as well.
>>>>>>>>>
>>>>>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>>>>>
>>>>>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>>>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>>>>>> module or to a bank. Basing on that I created my DT example above.
>>>>>>>>
>>>>>>>
>>>>>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>>>>>> out 0, 3 are mapped to BANK A
>>>>>>> out 1, 4 are mapped to BANK B
>>>>>>
>>>>>> Just noticed that I made a mistake in my example, it should have been:
>>>>>>
>>>>>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>>>>>
>>>>>>> out 2, 5 are mapped to BANK C
>>>>>>
>>>>>> Correct.
>>>>>>
>>>>>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>>>>>
>>>>>> That's right.
>>>>>>
>>>>>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>>>>>> led-sources = < 0 1 2 3 4 5 >;
>>>>>>
>>>>>> Why? This would be a mix of three banks. Like you listed above.
>>>>>> I'm still interpreting led-sources elements as iout identifiers.
>>>>>>
>>>>>
>>>>> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
>>>>> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.
>>>>
>>>> There is naming conflict I noticed just now - LEDn_BANK_EN bits
>>>> in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).
>>>>
>>>>> These OUTPUTs will appear as a single RGB LED grouping.
>>>>
>>>> Single? W would rather expect that we get two RGB LED modules, whose
>>>> brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
>>>> registers respectively.
>>>>
>>>>>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>>>>>
>>>>>>> non-banked case would be
>>>>>>> led-sources = < 0 1 2 >;
>>>>>>
>>>>>> Agreed here. It would be LED0 RGB LED module.
>>>>>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>>>>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>>>>>> are inherently mapped to the bank.
>>>>>>
>>>>>> To three separate banks, right?
>>>>>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
>>>>>
>>>>> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
>>>>> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
>>>>> color adjustment registers.
>>>>
>>>> Here as above, I would expect two separate banks - LED0 and LED1.
>>>> Moreover - not 3 color adjustment registers, but six - one per iout:
>>>> OUT0_COLOR to OUT5_COLOR.
>>>>
>>>
>>> When the LEDs are banked the banked LEDs are controlled by the bank registers not the LEDx registers
>>> so you should only see 3 color adjustments on the banked LEDs.
>>>
>>>>>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>>>>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>>>>>
>>>>>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>>>>>> LED file presented to the user space.
>>>>>>
>>>>>> I suspect there is logical clash here due to interpreting
>>>>>> led-sources elements as iouts in one case and LEDn modules
>>>>>> in the other case.
>>>>>>
>>>>>
>>>>> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
>>>>
>>>> We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
>>>> banks (A,B,C), which are enabled by default, am I right?
>>>
>>> No.  Independent LED modules are enabled by default.  You have to explicitly enable the banks.
>>>
>>>>
>>>> Bank A iouts: 0, 3 ,6, 9, 12, 15
>>>> Bank B iouts: 1, 4, 7, 10, 13, 16
>>>> Bank C iouts: 2, 5, 8, 11, 14, 17
>>>>
>>>> When RGB LED module is enabled (via LEDn_Bank_EN bit),
>>>> the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
>>>> lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
>>>> related OUTn_COLOR registers. Is it correct?
>>>
>>> No it is the opposite.  When the bit is enabled LED banking is enabled and the BANK brightness and color registers over
>>> ride the LEDx color and brightness registers.
>>>
>>> Default is independent control of the RGB via the LEDx color and brightness registers.
>>>
>>>>
>>>>> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
>>>>> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.
>>>>
>>>> Ekhm, I messed something here.
>>>>
>>>> So for this I would define a single LED class device.
>>>> Related DT node would not need led-sources at all,
>>>> but only ti,control-bank. The semantics would be:
>>>> controls all iouts not taken by RGB LED modules.
>>>>
>>>
>>> Hmm.  I guess I will put that on hold until you read the responses.  I am not sure that would work or
>>> that would be really clean.  I still believe that mapping led-sources to the LEDx module number is the cleanest
>>> simplest solution since the driver cannot inter mix different outputs for enablement.
>>
>> I've read the doc again more carefully and hopefully I finally have
>> proper understanding. Let's check it.
>>
>> 1. On reset LED_CONFIG0 bits are zeroed, which means
>>     LEDn module independent control mode.
>> 2. LEDn modules (i.e. IOUT triplets) are controlled independently,
>>     with use of LEDn_BRIGHTNESS registers, and each IOUT color can
>>     be adjusted using OUTn_CONTROL registers.
>> 3. LEDn_Bank_EN bits, when set to 1, assign given RGB LED module
>>     to one global bank, controlled via BANK_BRIGHTNESS and BANK_n_COLOR
>>     registers.
>>
>> Having that, I'd see led-sources definitions as follows
>> (led-sources element is IOUT identifier)
>>
>> 1.
>>
>> - LED0, LED1, LED2, LED3 modules controlled by separate
>>    LED class devices
>>
>> led-sources = <0 1 2>   // LED0
>> led-sources = <3 4 5>   // LED1
>> led-sources = <6 7 8>   // LED2
>> led-sources = <9 10 11> // LED3
>>
>> 2.
>>
>> - LED0 and LED3 modules assigned to the bank, and controlled
>>    by one LED class device,
>> - LED1 and LED2 modules controlled by separate LED class devices
>>
>> led-sources = <0 1 2 9 10 11> // Bank with LED0 and LED3
>> led-sources = <3 4 5>         // LED1
>> led-sources = <6 7 8>         // LED2
>>
>>
>> So now I see your point. It would be indeed easier
>> to switch to LEDn module identifiers for led-sources
>> elements. With that the definitions would look like
>> this:
>>
>>
>> 1.
>>
>> - LED0, LED1, LED2, LED3 modules controlled by separate
>>    LED class devices
>>
>> led-sources = <0>   // LED0
>> led-sources = <1>   // LED1
>> led-sources = <2>   // LED2
>> led-sources = <3>   // LED3
>>
>> 2.
>>
>> - LED0 and LED3 modules assigned to the bank, and controlled
>>    by one LED class device,
>> - LED1 and LED2 modules controlled by separate LED class devices
>>
>> led-sources = <0 3> // Bank with LED0 and LED3
>> led-sources = <1>   // LED1
>> led-sources = <2>   // LED2
>>
> 
> This is exactly how I submitted the code.
> 
>>
>> But, I don't think use of led-sources is justified in
>> this case. I propose to introduce device specific properties:
>>
>> ti,led-module and ti,led-bank
>>
>> With that we would have:
>>
>> ti,led-bank = <0 3>   // Bank with LED0 and LED3 modules
>> ti,led-module = <1>   // LED1
>> ti.led-module = <2>   // LED2
>>
> 
> We are now aligned.  I can change the led-sources to the TI specific if there are no further objections.
> In doing this I can eliminate the ti,control-bank property.
> 
>>
>>>> I would also add Table 1 contents (Bank Number and LED Number
>>>> Assignment) to the DT bindings.
>>>>
>>>
>>> Should I add that to the DT binding or reference the data sheet table since this driver will support 4 different devices
>>> with varying number of outputs from 18-36.
>>
>> My first thought was to show full table, but four different
>> mappings would add too much noise. So the reference to the data
>> sheet should suffice.
>>
> 
> OK
> 
> One last question I am going to add the LP5036 and 30 which have the same technology but slightly different register maps.
> Should I rename the driver to LP5036.c as the 30, 24 and 18 would technically be subsets?

How about leds-lp50xx.c ? You can also create a library like
drivers/leds/leds-lp55xx-common.c if that would simplify the code.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-09  6:46                                 ` Vesa Jääskeläinen
@ 2019-01-13 16:36                                   ` Jacek Anaszewski
  0 siblings, 0 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-13 16:36 UTC (permalink / raw)
  To: Vesa Jääskeläinen, Pavel Machek
  Cc: Dan Murphy, robh+dt, devicetree, linux-kernel, linux-leds

Hi Vesa,

On 1/9/19 7:46 AM, Vesa Jääskeläinen wrote:
> Hi Jacek,
> 
> On 07/01/2019 23.13, Jacek Anaszewski wrote:
>> Hi Vesa,
>>
>> On 1/5/19 1:39 AM, Vesa Jääskeläinen wrote:
>>> Hi Jacek,
>>>
>>> On 04/01/2019 23.37, Jacek Anaszewski wrote:
>>>> But, aside from that hypothetic issue, we need a solution for
>>>> LEDn_BRIGHTNESS feature of lp5024, i.e. setting color intensity
>>>> via a single register write. How would you propose to address that?
>>>
>>> You could model it to something like this in device tree:
>>>
>>> led-module @ <i2c-address> {
>>>      compatible = "lp5024";
>>>
>>>      // There is in hardware setup to use either linear or
>>>      // logarithmic scaling:
>>>      //enable-logarithmic-brightness;
>>>
>>>      led0 {
>>>          // this will create led instance for LED0 in lp5024
>>>          label = "lp-led0";
>>>
>>>          // This specifies LED number within lp5024
>>>          led-index = <0>;   // set output-base as 0*3 == 0
>>>
>>>          element-red {
>>>              // refers to OUT0
>>>              output-offset = <0>;
>>>          };
>>>
>>>          element-green {
>>>              // refers to OUT1
>>>              output-offset = <1>;
>>>          };
>>>
>>>          element-blue {
>>>              // refers to OUT2
>>>              output-offset = <2>;
>>>          };
>>>
>>>      };
>>>
>>>      led1 {
>>>          // this will create led instance for LED1 in lp5024
>>>          label = "lp-led1";
>>>
>>>          // This specifies LED number within lp5024
>>>          led-index = <1>;   // set output-base as 1*3 == 3
>>>
>>>          element-red {
>>>              // refers to OUT3
>>>              output-offset = <0>;
>>>          };
>>>
>>>          element-green {
>>>              // refers to OUT4
>>>              output-offset = <1>;
>>>          };
>>>
>>>          element-blue {
>>>              // refers to OUT5
>>>              output-offset = <2>;
>>>          };
>>>
>>>      };
>>>
>>>      bank-led {
>>>          // this will create led instance for bank leds in lp5024
>>>          label = "lp-bank-led";
>>>
>>>          // configured bank led configuration
>>>          led-index = <2 3 4 5 6 7>;
>>>          // As here is list of led-indices this entry is
>>>          // assumed to be bank configuration. Bank mode is enable
>>>          // for the indices.
>>>
>>>          // set output-base as BANK A
>>>
>>>          element-red {
>>>              // refers to BANK A
>>>              output-offset = <0>;
>>>          };
>>>
>>>          element-green {
>>>              // refers to BANK B
>>>              output-offset = <1>;
>>>          };
>>>
>>>          element-blue {
>>>              // refers to BANK C
>>>              output-offset = <2>;
>>>          };
>>>      };
>>> };
>>>
>>> This would then create three led instances and each led instance has 
>>> brightness setting and that goes straight to hardware.
>>>
>>> If one would want to override hardware control for brightness then I 
>>> suppose you would define in led node something like:
>>>
>>>      brightness-model = "hsl"
>>>
>>> This would then pick red, green and blue elements for hsl 
>>> calculations and others color elements for linear. LED specific 
>>> hardware brightness would then be either 0 or 0xFF depending if all 
>>> of LED color elements are zero or not.
>>>
>>> Would that kind of model work?
>>
>> I'd prefer to have single RGB LED device. And your DT design
>> is unnecessarily complex and a bit confusing.
> 
> As this chip series is kinda designed for N x RGB LED's my idea was that 
> if from user space point of view we model it as N times of individual 
> RGB LED instances that may not even have anything to do with together. 
> Eg. could be used for different purposes and such.

Actually the only differences between your DT design and that
initially proposed by Dan are element-* nodes describing
IOUT -> color mapping.

I am not sure if LEDn_BRIGHTNESS feature would work as intended
when colors are not assigned to IOUTs in the order shown on the
Figure 14. in the data sheet. I'm afraid that we would be changing
hue as well (sticking to the HSV nomenclature). Let's not bother with
covering arrangements not being in line with the data sheet
recommendations.

Of course the element-color nodes will be necessary for leds-pwm,
like in your github example.

> And in device tree one would define logical connections for the leds so 
> they would be mapped logically correct to user space.
> 
> If one would define it like:
> 
> led1 {
>      // this will create led instance for LED1 in lp5024
>      label = "lp-led1";
> 
>      // This specifies LED number within lp5024
>      led-sources = <1>;
> };
> (note changed led-index to led-sources as that is what Pavel had and 
> preferred)
> 
> We could assume that it is RGB led in this driver's case and create it 
> automatically with elements "red", "green", and "blue". And this could 
> then be mapped automatically to HSL color elements or what ever the 
> model would be.
> 
> If you would model it differently in your hardware design then you would 
> need to define more device tree nodes. Eg. if your order of LEDs would 
> not be red, green, blue. Or if you would have non-RGB led(s) in there.
> 
>> Also, you provided scarce information about sysfs interface.
>> It would be nice to see the sequence of commands.
> 
> In this case it could be:
> 
> # Note: Updated color to value array model.
> 
> $ ls /sys/class/leds
> lp-led0    lp-led1    lp-bank-led
> 
> $ ls /sys/class/leds/lp-led0
> brightness    color
> 
> $ ls /sys/class/leds/lp-led1
> brightness    color
> 
> $ ls /sys/class/leds/lp-bank-led
> brightness    color
> 
> # Idea of above is that as brightness is for triplet:
> #   OUT(LED*3 + 0), OUT(LED*3 + 1), OUT(LED*3 + 2),
> # Then if we model it like RGB LED then brightness would automatically
> # map to correct OUTputs and be grouped from user space point of view
> # logically in correct place.
> 
> # set first led to red
> echo "255 0 0" > /sys/class/leds/lp-led0/color
> 
> # set second led to green
> echo "0 255 0" > /sys/class/leds/lp-led1/color
> 
> # set bank led to blue
> echo "0 0 255" > /sys/class/leds/lp-bank-led/color
> 
> # Set hardware brightness control to middle
> echo "128" > /sys/class/leds/lp-bank-led/brightness
> 
> # If we would have software controlled virtual brightness enabled for
> # particular led classdev then there would be some math in either user
> # or in kernel space.
> 
> Thanks,
> Vesa Jääskeläinen
> 

-- 
Best regards,
Jacek Anaszewski

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

* Re: Generic RGB LED support was Re: [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver
  2019-01-09  7:11                                           ` Vesa Jääskeläinen
@ 2019-01-13 16:37                                             ` Jacek Anaszewski
  0 siblings, 0 replies; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-13 16:37 UTC (permalink / raw)
  To: Vesa Jääskeläinen, Pavel Machek, Dan Murphy
  Cc: robh+dt, devicetree, linux-kernel, linux-leds

Hi Vesa,

On 1/9/19 8:11 AM, Vesa Jääskeläinen wrote:
> Hi Pavel,
> 
> On 09/01/2019 0.59, Pavel Machek wrote:
>> Hi!
>>
>>>>>> Grab yourself an RGB LED and play with it; you'll see what the
>>>>>> problems are. It is hard to explain colors over email...
>>>>>
>>>>> Video [0] gives some overview of lp5024 capabilities.
>>>>>
>>>>> I don't see any problems in exposing separate red,green,blue
>>>>> files and brightness for the devices with hardware support for
>>>>> that.
>>>>
>>>> Well, that's what we do today, as three separate LEDs, right?
>>>
>>> No. It doesn't allow for setting color intensity by having
>>> the color fixed beforehand. Below is relevant excerpt from
>>> the lp5024 documentation. This is not something that can be
>>> mapped to RGB color space, but rather to HSV/HSL, with the
>>> reservation that the hardware implementation uses PWM
>>> for setting color intensity.
>>
>> So they have feature where they have independent controls for each
>> channel, then one common control per three channels. Other chips have
>> common control for all the LEDs, for example. We don't support that
>> currently; lets focus on the RGB thing first.
>>
>>>> I don't have problem with that, either; other drivers already do
>>>> that. He's free to use existing same interface.
>>>>
>>>> But that is insufficient, as it does not allow simple stuff, such as
>>>> turning led "white".
>>>>
>>>> So... perhaps we should agree on requirements, first, and then we can
>>>> discuss solutions?
>>>>
>>>> Requirements for RGB LED interface:
>>>>
>>>> 1) Userspace should be able to set the white color
>>>>
>>>> 2) Userspace should be able to arbitrary color from well known list
>>>> and it should approximately match what would CRT, LCD or OLED 
>>>> monitor display
>>>
>>> The difference is that monitor display driver is pre-calibrated
>>> for given display by the manufacturer. With the LED controllers the
>>> manufacturer has no control over what LEDs will be connected to the
>>> iouts. Therefore it should be not surprising that colors produced
>>> by custom LEDs are not as user would expect when comparing to
>>> the RGB color displayed on the monitor display.
>>
>> It is true that _chip_ manufacturer can not know what LEDs will be
>> connected. But _system_ manufacturer can and should know that, and
>> should tell be able to tell us in the dts.
>>
>>> This renders your requirement 2) infeasible with use of custom LEDs
>>> any fixed algorithm, since the final effect will always heavily depend
>>> on the LED circuit design.
>>
>> Depending on LED circuit design and actual LEDs connected is okay.. we
>> just need to get information from _system_ designer (not chip
>> designer), and pass it to a place where color is computed.
>>
>>>> a) RGB LEDs are usually not balanced. Setting 100% PWM on
>>>> red/green/blue channels will result in nothing close to white
>>>> light. In fact, to get white light on N900, blue and green channel's
>>>> PWM needs to be set pretty low, as in 5%.
>>>>
>>>> b) LED class does not define any relation between "brightness" in
>>>> sysfs and ammount of light in lumens. Some drivers use close to linear
>>>> relation, some use exponential relation. Human eyes percieve logarithm
>>>> of lumens. RGB color model uses even more complex function.
>>>
>>> One general question: do you have any solutions in store?
>>
>> I played with LEDs on N900 over the weekend, yes.
>>
>> And getting reasonable colors seems to be possible, when a) and b) are
>> solved... a) seems to be more important than b).
>>
>> Now... this does not tell us how we should design kernel<->user
>> interface, but it should tell us that main goals - 1) and 2) are
>> possible.
> 
> I was thinking about this calibration and color correctness thing and I 
> am thinking a bit that it should be partly in kernel and partly in user 
> space.
> 
> For displays and printers there are defined icc-profiles that define how 
> colors are mapped to particular device in cases when you want to have 
> accurate color representation. In theory to get accurate LED output one 
> could model LEDs with icc profile and then pick your color and convert 
> it with icc profile to actual raw hardware values. Then this raw 
> hardware value could be written from user space to kernel.

icc-profiles idea sounds interesting. We would have to adjust hsv->rgb
algorithm to take the profiles into account. I wonder how that would
work in practice.

> In kernel we could provide raw hardware value support and in case of PWM 
> IC controlled LEDs we could provide curve mapping to linearize the 
> behavior of values entered to enable use in cases where close enough is 
> good enough.
> 
> Eg. if you want to have "white" then you have your color space picker 
> like sRGB(255,255,255). Then you would define icc profile it might 
> translate to hardware raw values 253%, 230%, 225%.

> Then you would write this to kernel with:
> 
> # set red, green and blue color elements
> echo "253 230 225" > color
> 
> In this case however behavior of brightness node is challening in 
> accuracy domain. Britghtness value 255 would of course provide 1:1 
> mapping in this case.
> 
> To go right to correct color and brightness at one go we could have 
> optional brightness at the end of color value array:
> 
> # set red, green and blue color element and brightness setting:
> echo "253 230 225 255" > color
> 
> If you want to have fancier behavior for brightness in your system then 
> we probably need to have configurable brightness model.
> 
> - hardware, like in lp5024 case would map to hardware register (would be 
> omitted if there is no such register)
> - onoff, would act like light switch ON/OFF eg. either configured value 
> or all zeroes.
> - scaled, would multiply the color elements
> - hsl, would use hsl formula
> - and this can be extended later with some other models and allows us to 
> start with with some models now.
> 
> We could define this in devicetree and from sysfs a bit like with trigger:
> 
> $ cat brightness_model
> [hardware] onoff scaled hsl
> 
> $ echo "hsl" > brightness_model
> 
> $ cat brightness_model
> hardware onoff scaled [hsl]
> 
> Then we could have "color_names" or such sysfs entry to determine allow 
> user space auto detection of led elements):
> 
> $ cat color_names
> red green blue
> 
> I suppose this model would provide flexibilty for multiple cases. Make 
> it simple for most uses, allow accuracy with icc profiles for advanced 
> users, would allow atomic color setting.
> 
> I have updated (not yet in github) my tests to use color array model and 
> color_names already and can play with brightness_model thing if this is 
> something that is good path?
> 
> What do you think?

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-12 19:48                                   ` Jacek Anaszewski
@ 2019-01-14 12:27                                     ` Dan Murphy
  2019-01-14 20:11                                       ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-14 12:27 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/12/19 1:48 PM, Jacek Anaszewski wrote:
> Hi Dan,
> 
> On 1/12/19 6:09 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/11/19 3:52 PM, Jacek Anaszewski wrote:
>>> Dan,
>>>
>>> On 1/11/19 1:38 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> Sorry I missed some replies
>>>>
>>>> On 1/10/19 4:03 PM, Jacek Anaszewski wrote:
>>>>> On 1/10/19 9:43 PM, Dan Murphy wrote:
>>>>>> Jacek
>>>>>>
>>>>>> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>>>>>>> Dan,
>>>>>>>
>>>>>>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>>>>>>> Jacek
>>>>>>>>
>>>>>>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>>>>>>> Hi Dan,
>>>>>>>>>
>>>>>>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>>>>>>> Jacek
>>>>>>>>>>
>>>>>>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>> Hi Dan,
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>> Jacek
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>>>> Dan,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>           .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>>>>>>           1 file changed, 63 insertions(+)
>>>>>>>>>>>>>>>>>>           create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>>>>>>> +    };
>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> That will work too.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>>>>>>> triplets somehow then?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>>>>>>
>>>>>>>>>>>>> led-sources should map to iouts directly.
>>>>>>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>>>>>>
>>>>>>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>>>>>>> and so on.
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> for banks:
>>>>>>>>>>>>>
>>>>>>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>>>>>>
>>>>>>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>>>>>>
>>>>>>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>>>>>>> registers.
>>>>>>>>>>>
>>>>>>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>>>>>>> for such purposes.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Yes Pavel also mentioned that as well.
>>>>>>>>>>
>>>>>>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>>>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>>>>>>
>>>>>>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>>>>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>>>>>>> module or to a bank. Basing on that I created my DT example above.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>>>>>>> out 0, 3 are mapped to BANK A
>>>>>>>> out 1, 4 are mapped to BANK B
>>>>>>>
>>>>>>> Just noticed that I made a mistake in my example, it should have been:
>>>>>>>
>>>>>>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>>>>>>
>>>>>>>> out 2, 5 are mapped to BANK C
>>>>>>>
>>>>>>> Correct.
>>>>>>>
>>>>>>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>>>>>>
>>>>>>> That's right.
>>>>>>>
>>>>>>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>>>>>>> led-sources = < 0 1 2 3 4 5 >;
>>>>>>>
>>>>>>> Why? This would be a mix of three banks. Like you listed above.
>>>>>>> I'm still interpreting led-sources elements as iout identifiers.
>>>>>>>
>>>>>>
>>>>>> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
>>>>>> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.
>>>>>
>>>>> There is naming conflict I noticed just now - LEDn_BANK_EN bits
>>>>> in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).
>>>>>
>>>>>> These OUTPUTs will appear as a single RGB LED grouping.
>>>>>
>>>>> Single? W would rather expect that we get two RGB LED modules, whose
>>>>> brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
>>>>> registers respectively.
>>>>>
>>>>>>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>>>>>>
>>>>>>>> non-banked case would be
>>>>>>>> led-sources = < 0 1 2 >;
>>>>>>>
>>>>>>> Agreed here. It would be LED0 RGB LED module.
>>>>>>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>>>>>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>>>>>>> are inherently mapped to the bank.
>>>>>>>
>>>>>>> To three separate banks, right?
>>>>>>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
>>>>>>
>>>>>> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
>>>>>> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
>>>>>> color adjustment registers.
>>>>>
>>>>> Here as above, I would expect two separate banks - LED0 and LED1.
>>>>> Moreover - not 3 color adjustment registers, but six - one per iout:
>>>>> OUT0_COLOR to OUT5_COLOR.
>>>>>
>>>>
>>>> When the LEDs are banked the banked LEDs are controlled by the bank registers not the LEDx registers
>>>> so you should only see 3 color adjustments on the banked LEDs.
>>>>
>>>>>>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>>>>>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>>>>>>
>>>>>>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>>>>>>> LED file presented to the user space.
>>>>>>>
>>>>>>> I suspect there is logical clash here due to interpreting
>>>>>>> led-sources elements as iouts in one case and LEDn modules
>>>>>>> in the other case.
>>>>>>>
>>>>>>
>>>>>> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
>>>>>
>>>>> We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
>>>>> banks (A,B,C), which are enabled by default, am I right?
>>>>
>>>> No.  Independent LED modules are enabled by default.  You have to explicitly enable the banks.
>>>>
>>>>>
>>>>> Bank A iouts: 0, 3 ,6, 9, 12, 15
>>>>> Bank B iouts: 1, 4, 7, 10, 13, 16
>>>>> Bank C iouts: 2, 5, 8, 11, 14, 17
>>>>>
>>>>> When RGB LED module is enabled (via LEDn_Bank_EN bit),
>>>>> the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
>>>>> lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
>>>>> related OUTn_COLOR registers. Is it correct?
>>>>
>>>> No it is the opposite.  When the bit is enabled LED banking is enabled and the BANK brightness and color registers over
>>>> ride the LEDx color and brightness registers.
>>>>
>>>> Default is independent control of the RGB via the LEDx color and brightness registers.
>>>>
>>>>>
>>>>>> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
>>>>>> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.
>>>>>
>>>>> Ekhm, I messed something here.
>>>>>
>>>>> So for this I would define a single LED class device.
>>>>> Related DT node would not need led-sources at all,
>>>>> but only ti,control-bank. The semantics would be:
>>>>> controls all iouts not taken by RGB LED modules.
>>>>>
>>>>
>>>> Hmm.  I guess I will put that on hold until you read the responses.  I am not sure that would work or
>>>> that would be really clean.  I still believe that mapping led-sources to the LEDx module number is the cleanest
>>>> simplest solution since the driver cannot inter mix different outputs for enablement.
>>>
>>> I've read the doc again more carefully and hopefully I finally have
>>> proper understanding. Let's check it.
>>>
>>> 1. On reset LED_CONFIG0 bits are zeroed, which means
>>>     LEDn module independent control mode.
>>> 2. LEDn modules (i.e. IOUT triplets) are controlled independently,
>>>     with use of LEDn_BRIGHTNESS registers, and each IOUT color can
>>>     be adjusted using OUTn_CONTROL registers.
>>> 3. LEDn_Bank_EN bits, when set to 1, assign given RGB LED module
>>>     to one global bank, controlled via BANK_BRIGHTNESS and BANK_n_COLOR
>>>     registers.
>>>
>>> Having that, I'd see led-sources definitions as follows
>>> (led-sources element is IOUT identifier)
>>>
>>> 1.
>>>
>>> - LED0, LED1, LED2, LED3 modules controlled by separate
>>>    LED class devices
>>>
>>> led-sources = <0 1 2>   // LED0
>>> led-sources = <3 4 5>   // LED1
>>> led-sources = <6 7 8>   // LED2
>>> led-sources = <9 10 11> // LED3
>>>
>>> 2.
>>>
>>> - LED0 and LED3 modules assigned to the bank, and controlled
>>>    by one LED class device,
>>> - LED1 and LED2 modules controlled by separate LED class devices
>>>
>>> led-sources = <0 1 2 9 10 11> // Bank with LED0 and LED3
>>> led-sources = <3 4 5>         // LED1
>>> led-sources = <6 7 8>         // LED2
>>>
>>>
>>> So now I see your point. It would be indeed easier
>>> to switch to LEDn module identifiers for led-sources
>>> elements. With that the definitions would look like
>>> this:
>>>
>>>
>>> 1.
>>>
>>> - LED0, LED1, LED2, LED3 modules controlled by separate
>>>    LED class devices
>>>
>>> led-sources = <0>   // LED0
>>> led-sources = <1>   // LED1
>>> led-sources = <2>   // LED2
>>> led-sources = <3>   // LED3
>>>
>>> 2.
>>>
>>> - LED0 and LED3 modules assigned to the bank, and controlled
>>>    by one LED class device,
>>> - LED1 and LED2 modules controlled by separate LED class devices
>>>
>>> led-sources = <0 3> // Bank with LED0 and LED3
>>> led-sources = <1>   // LED1
>>> led-sources = <2>   // LED2
>>>
>>
>> This is exactly how I submitted the code.
>>
>>>
>>> But, I don't think use of led-sources is justified in
>>> this case. I propose to introduce device specific properties:
>>>
>>> ti,led-module and ti,led-bank
>>>
>>> With that we would have:
>>>
>>> ti,led-bank = <0 3>   // Bank with LED0 and LED3 modules
>>> ti,led-module = <1>   // LED1
>>> ti.led-module = <2>   // LED2
>>>
>>
>> We are now aligned.  I can change the led-sources to the TI specific if there are no further objections.
>> In doing this I can eliminate the ti,control-bank property.
>>
>>>
>>>>> I would also add Table 1 contents (Bank Number and LED Number
>>>>> Assignment) to the DT bindings.
>>>>>
>>>>
>>>> Should I add that to the DT binding or reference the data sheet table since this driver will support 4 different devices
>>>> with varying number of outputs from 18-36.
>>>
>>> My first thought was to show full table, but four different
>>> mappings would add too much noise. So the reference to the data
>>> sheet should suffice.
>>>
>>
>> OK
>>
>> One last question I am going to add the LP5036 and 30 which have the same technology but slightly different register maps.
>> Should I rename the driver to LP5036.c as the 30, 24 and 18 would technically be subsets?
> 
> How about leds-lp50xx.c ? You can also create a library like
> drivers/leds/leds-lp55xx-common.c if that would simplify the code.
> 

A library would be overkill.
Is it just the DT that we don't want to use wild cards in naming?

leds-lp50xx.c is a fine name to me.

Dan

-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-14 12:27                                     ` Dan Murphy
@ 2019-01-14 20:11                                       ` Jacek Anaszewski
  2019-01-14 20:14                                         ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-14 20:11 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Hi Dan,

On 1/14/19 1:27 PM, Dan Murphy wrote:
> Jacek
> 
> On 1/12/19 1:48 PM, Jacek Anaszewski wrote:
>> Hi Dan,
>>
>> On 1/12/19 6:09 PM, Dan Murphy wrote:
>>> Jacek
>>>
>>> On 1/11/19 3:52 PM, Jacek Anaszewski wrote:
>>>> Dan,
>>>>
>>>> On 1/11/19 1:38 PM, Dan Murphy wrote:
>>>>> Jacek
>>>>>
>>>>> Sorry I missed some replies
>>>>>
>>>>> On 1/10/19 4:03 PM, Jacek Anaszewski wrote:
>>>>>> On 1/10/19 9:43 PM, Dan Murphy wrote:
>>>>>>> Jacek
>>>>>>>
>>>>>>> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>>>>>>>> Dan,
>>>>>>>>
>>>>>>>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>>>>>>>> Jacek
>>>>>>>>>
>>>>>>>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>>>>>>>> Hi Dan,
>>>>>>>>>>
>>>>>>>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>>>>>>>> Jacek
>>>>>>>>>>>
>>>>>>>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>> Hi Dan,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>>> Jacek
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>>>>> Dan,
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>            .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>>>>>>>            1 file changed, 63 insertions(+)
>>>>>>>>>>>>>>>>>>>            create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>>>>>>>> +    };
>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> That will work too.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>>>>>>>> triplets somehow then?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> led-sources should map to iouts directly.
>>>>>>>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>>>>>>>> and so on.
>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> for banks:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>>>>>>>> registers.
>>>>>>>>>>>>
>>>>>>>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>>>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>>>>>>>> for such purposes.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Yes Pavel also mentioned that as well.
>>>>>>>>>>>
>>>>>>>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>>>>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>>>>>>>
>>>>>>>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>>>>>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>>>>>>>> module or to a bank. Basing on that I created my DT example above.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>>>>>>>> out 0, 3 are mapped to BANK A
>>>>>>>>> out 1, 4 are mapped to BANK B
>>>>>>>>
>>>>>>>> Just noticed that I made a mistake in my example, it should have been:
>>>>>>>>
>>>>>>>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>>>>>>>
>>>>>>>>> out 2, 5 are mapped to BANK C
>>>>>>>>
>>>>>>>> Correct.
>>>>>>>>
>>>>>>>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>>>>>>>
>>>>>>>> That's right.
>>>>>>>>
>>>>>>>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>>>>>>>> led-sources = < 0 1 2 3 4 5 >;
>>>>>>>>
>>>>>>>> Why? This would be a mix of three banks. Like you listed above.
>>>>>>>> I'm still interpreting led-sources elements as iout identifiers.
>>>>>>>>
>>>>>>>
>>>>>>> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
>>>>>>> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.
>>>>>>
>>>>>> There is naming conflict I noticed just now - LEDn_BANK_EN bits
>>>>>> in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).
>>>>>>
>>>>>>> These OUTPUTs will appear as a single RGB LED grouping.
>>>>>>
>>>>>> Single? W would rather expect that we get two RGB LED modules, whose
>>>>>> brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
>>>>>> registers respectively.
>>>>>>
>>>>>>>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>>>>>>>
>>>>>>>>> non-banked case would be
>>>>>>>>> led-sources = < 0 1 2 >;
>>>>>>>>
>>>>>>>> Agreed here. It would be LED0 RGB LED module.
>>>>>>>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>>>>>>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>>>>>>>> are inherently mapped to the bank.
>>>>>>>>
>>>>>>>> To three separate banks, right?
>>>>>>>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
>>>>>>>
>>>>>>> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
>>>>>>> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
>>>>>>> color adjustment registers.
>>>>>>
>>>>>> Here as above, I would expect two separate banks - LED0 and LED1.
>>>>>> Moreover - not 3 color adjustment registers, but six - one per iout:
>>>>>> OUT0_COLOR to OUT5_COLOR.
>>>>>>
>>>>>
>>>>> When the LEDs are banked the banked LEDs are controlled by the bank registers not the LEDx registers
>>>>> so you should only see 3 color adjustments on the banked LEDs.
>>>>>
>>>>>>>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>>>>>>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>>>>>>>
>>>>>>>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>>>>>>>> LED file presented to the user space.
>>>>>>>>
>>>>>>>> I suspect there is logical clash here due to interpreting
>>>>>>>> led-sources elements as iouts in one case and LEDn modules
>>>>>>>> in the other case.
>>>>>>>>
>>>>>>>
>>>>>>> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
>>>>>>
>>>>>> We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
>>>>>> banks (A,B,C), which are enabled by default, am I right?
>>>>>
>>>>> No.  Independent LED modules are enabled by default.  You have to explicitly enable the banks.
>>>>>
>>>>>>
>>>>>> Bank A iouts: 0, 3 ,6, 9, 12, 15
>>>>>> Bank B iouts: 1, 4, 7, 10, 13, 16
>>>>>> Bank C iouts: 2, 5, 8, 11, 14, 17
>>>>>>
>>>>>> When RGB LED module is enabled (via LEDn_Bank_EN bit),
>>>>>> the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
>>>>>> lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
>>>>>> related OUTn_COLOR registers. Is it correct?
>>>>>
>>>>> No it is the opposite.  When the bit is enabled LED banking is enabled and the BANK brightness and color registers over
>>>>> ride the LEDx color and brightness registers.
>>>>>
>>>>> Default is independent control of the RGB via the LEDx color and brightness registers.
>>>>>
>>>>>>
>>>>>>> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
>>>>>>> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.
>>>>>>
>>>>>> Ekhm, I messed something here.
>>>>>>
>>>>>> So for this I would define a single LED class device.
>>>>>> Related DT node would not need led-sources at all,
>>>>>> but only ti,control-bank. The semantics would be:
>>>>>> controls all iouts not taken by RGB LED modules.
>>>>>>
>>>>>
>>>>> Hmm.  I guess I will put that on hold until you read the responses.  I am not sure that would work or
>>>>> that would be really clean.  I still believe that mapping led-sources to the LEDx module number is the cleanest
>>>>> simplest solution since the driver cannot inter mix different outputs for enablement.
>>>>
>>>> I've read the doc again more carefully and hopefully I finally have
>>>> proper understanding. Let's check it.
>>>>
>>>> 1. On reset LED_CONFIG0 bits are zeroed, which means
>>>>      LEDn module independent control mode.
>>>> 2. LEDn modules (i.e. IOUT triplets) are controlled independently,
>>>>      with use of LEDn_BRIGHTNESS registers, and each IOUT color can
>>>>      be adjusted using OUTn_CONTROL registers.
>>>> 3. LEDn_Bank_EN bits, when set to 1, assign given RGB LED module
>>>>      to one global bank, controlled via BANK_BRIGHTNESS and BANK_n_COLOR
>>>>      registers.
>>>>
>>>> Having that, I'd see led-sources definitions as follows
>>>> (led-sources element is IOUT identifier)
>>>>
>>>> 1.
>>>>
>>>> - LED0, LED1, LED2, LED3 modules controlled by separate
>>>>     LED class devices
>>>>
>>>> led-sources = <0 1 2>   // LED0
>>>> led-sources = <3 4 5>   // LED1
>>>> led-sources = <6 7 8>   // LED2
>>>> led-sources = <9 10 11> // LED3
>>>>
>>>> 2.
>>>>
>>>> - LED0 and LED3 modules assigned to the bank, and controlled
>>>>     by one LED class device,
>>>> - LED1 and LED2 modules controlled by separate LED class devices
>>>>
>>>> led-sources = <0 1 2 9 10 11> // Bank with LED0 and LED3
>>>> led-sources = <3 4 5>         // LED1
>>>> led-sources = <6 7 8>         // LED2
>>>>
>>>>
>>>> So now I see your point. It would be indeed easier
>>>> to switch to LEDn module identifiers for led-sources
>>>> elements. With that the definitions would look like
>>>> this:
>>>>
>>>>
>>>> 1.
>>>>
>>>> - LED0, LED1, LED2, LED3 modules controlled by separate
>>>>     LED class devices
>>>>
>>>> led-sources = <0>   // LED0
>>>> led-sources = <1>   // LED1
>>>> led-sources = <2>   // LED2
>>>> led-sources = <3>   // LED3
>>>>
>>>> 2.
>>>>
>>>> - LED0 and LED3 modules assigned to the bank, and controlled
>>>>     by one LED class device,
>>>> - LED1 and LED2 modules controlled by separate LED class devices
>>>>
>>>> led-sources = <0 3> // Bank with LED0 and LED3
>>>> led-sources = <1>   // LED1
>>>> led-sources = <2>   // LED2
>>>>
>>>
>>> This is exactly how I submitted the code.
>>>
>>>>
>>>> But, I don't think use of led-sources is justified in
>>>> this case. I propose to introduce device specific properties:
>>>>
>>>> ti,led-module and ti,led-bank
>>>>
>>>> With that we would have:
>>>>
>>>> ti,led-bank = <0 3>   // Bank with LED0 and LED3 modules
>>>> ti,led-module = <1>   // LED1
>>>> ti.led-module = <2>   // LED2
>>>>
>>>
>>> We are now aligned.  I can change the led-sources to the TI specific if there are no further objections.
>>> In doing this I can eliminate the ti,control-bank property.
>>>
>>>>
>>>>>> I would also add Table 1 contents (Bank Number and LED Number
>>>>>> Assignment) to the DT bindings.
>>>>>>
>>>>>
>>>>> Should I add that to the DT binding or reference the data sheet table since this driver will support 4 different devices
>>>>> with varying number of outputs from 18-36.
>>>>
>>>> My first thought was to show full table, but four different
>>>> mappings would add too much noise. So the reference to the data
>>>> sheet should suffice.
>>>>
>>>
>>> OK
>>>
>>> One last question I am going to add the LP5036 and 30 which have the same technology but slightly different register maps.
>>> Should I rename the driver to LP5036.c as the 30, 24 and 18 would technically be subsets?
>>
>> How about leds-lp50xx.c ? You can also create a library like
>> drivers/leds/leds-lp55xx-common.c if that would simplify the code.
>>
> 
> A library would be overkill.
> Is it just the DT that we don't want to use wild cards in naming?

DT is for concrete board and cpu, so it doesn't make sense to
use wildcards in *.dts file names.

> leds-lp50xx.c is a fine name to me.

Apart of that, I've been also mulling over if we shouldn't go for single
"color" sysfs file for setting r,g,b components at one go.
I don't see any downsides. There is no risk that number of elements will
grow, and the benefit will be an atomic way of setting color - the
feature people are looking for. Vesa was mentioning the case where lack
of it had been a real problem [0].

Let's check the usability of such interface.

[0] https://lkml.org/lkml/2019/1/4/519

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-14 20:11                                       ` Jacek Anaszewski
@ 2019-01-14 20:14                                         ` Dan Murphy
  2019-01-14 20:28                                           ` Jacek Anaszewski
  0 siblings, 1 reply; 106+ messages in thread
From: Dan Murphy @ 2019-01-14 20:14 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/14/19 2:11 PM, Jacek Anaszewski wrote:
> Hi Dan,
> 
> On 1/14/19 1:27 PM, Dan Murphy wrote:
>> Jacek
>>
>> On 1/12/19 1:48 PM, Jacek Anaszewski wrote:
>>> Hi Dan,
>>>
>>> On 1/12/19 6:09 PM, Dan Murphy wrote:
>>>> Jacek
>>>>
>>>> On 1/11/19 3:52 PM, Jacek Anaszewski wrote:
>>>>> Dan,
>>>>>
>>>>> On 1/11/19 1:38 PM, Dan Murphy wrote:
>>>>>> Jacek
>>>>>>
>>>>>> Sorry I missed some replies
>>>>>>
>>>>>> On 1/10/19 4:03 PM, Jacek Anaszewski wrote:
>>>>>>> On 1/10/19 9:43 PM, Dan Murphy wrote:
>>>>>>>> Jacek
>>>>>>>>
>>>>>>>> On 1/10/19 1:57 PM, Jacek Anaszewski wrote:
>>>>>>>>> Dan,
>>>>>>>>>
>>>>>>>>> On 1/10/19 8:22 PM, Dan Murphy wrote:
>>>>>>>>>> Jacek
>>>>>>>>>>
>>>>>>>>>> On 1/10/19 12:44 PM, Jacek Anaszewski wrote:
>>>>>>>>>>> Hi Dan,
>>>>>>>>>>>
>>>>>>>>>>> On 1/9/19 10:31 PM, Dan Murphy wrote:
>>>>>>>>>>>> Jacek
>>>>>>>>>>>>
>>>>>>>>>>>> On 1/9/19 3:28 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>> On 1/9/19 10:12 PM, Dan Murphy wrote:
>>>>>>>>>>>>>> On 1/9/19 2:12 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>> Hi Dan,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 1/8/19 10:22 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>> On 1/8/19 3:16 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>>>> On 1/8/19 9:53 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>>>> Jacek
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On 1/8/19 2:33 PM, Jacek Anaszewski wrote:
>>>>>>>>>>>>>>>>>>> Dan,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On 12/19/18 5:26 PM, Dan Murphy wrote:
>>>>>>>>>>>>>>>>>>>> Introduce the bindings for the Texas Instruments LP5024 and the LP5018
>>>>>>>>>>>>>>>>>>>> RGB LED device driver.  The LP5024/18 can control RGB LEDs individually
>>>>>>>>>>>>>>>>>>>> or as part of a control bank group.  These devices have the ability
>>>>>>>>>>>>>>>>>>>> to adjust the mixing control for the RGB LEDs to obtain different colors
>>>>>>>>>>>>>>>>>>>> independent of the overall brightness of the LED grouping.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Datasheet:
>>>>>>>>>>>>>>>>>>>> http://www.ti.com/lit/ds/symlink/lp5024.pdf
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>>>>>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>>>>>            .../devicetree/bindings/leds/leds-lp5024.txt  | 63 +++++++++++++++++++
>>>>>>>>>>>>>>>>>>>>            1 file changed, 63 insertions(+)
>>>>>>>>>>>>>>>>>>>>            create mode 100644 Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> diff --git a/Documentation/devicetree/bindings/leds/leds-lp5024.txt b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>>>>>>>>> index 000000000000..9567aa6f7813
>>>>>>>>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>>>>>>>>> +++ b/Documentation/devicetree/bindings/leds/leds-lp5024.txt
>>>>>>>>>>>>>>>>>>>> @@ -0,0 +1,63 @@
>>>>>>>>>>>>>>>>>>>> +* Texas Instruments - LP5024/18 RGB LED driver
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +The LM3692x is an ultra-compact, highly efficient,
>>>>>>>>>>>>>>>>>>>> +white-LED driver designed for LCD display backlighting.
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +The main difference between the LP5024 and L5018 is the number of
>>>>>>>>>>>>>>>>>>>> +RGB LEDs they support.  The LP5024 supports twenty four strings while the
>>>>>>>>>>>>>>>>>>>> +LP5018 supports eighteen strings.
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +Required properties:
>>>>>>>>>>>>>>>>>>>> +    - compatible:
>>>>>>>>>>>>>>>>>>>> +        "ti,lp5018"
>>>>>>>>>>>>>>>>>>>> +        "ti,lp5024"
>>>>>>>>>>>>>>>>>>>> +    - reg :  I2C slave address
>>>>>>>>>>>>>>>>>>>> +    - #address-cells : 1
>>>>>>>>>>>>>>>>>>>> +    - #size-cells : 0
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +Optional properties:
>>>>>>>>>>>>>>>>>>>> +    - enable-gpios : gpio pin to enable/disable the device.
>>>>>>>>>>>>>>>>>>>> +    - vled-supply : LED supply
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +Required child properties:
>>>>>>>>>>>>>>>>>>>> +    - reg : Is the child node iteration.
>>>>>>>>>>>>>>>>>>>> +    - led-sources : LP5024 - 0 - 7
>>>>>>>>>>>>>>>>>>>> +            LP5018 - 0 - 5
>>>>>>>>>>>>>>>>>>>> +            Declares the LED string or strings that the child node
>>>>>>>>>>>>>>>>>>>> +            will control.  If ti,control-bank is set then this
>>>>>>>>>>>>>>>>>>>> +            property will contain multiple LED IDs.
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +Optional child properties:
>>>>>>>>>>>>>>>>>>>> +    - label : see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>>>>>> +    - linux,default-trigger :
>>>>>>>>>>>>>>>>>>>> +       see Documentation/devicetree/bindings/leds/common.txt
>>>>>>>>>>>>>>>>>>>> +    - ti,control-bank : Indicates that the LED strings declared in the
>>>>>>>>>>>>>>>>>>>> +                led-sources property are grouped within a control
>>>>>>>>>>>>>>>>>>>> +                bank for brightness and mixing control.
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +Example:
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +led-controller@28 {
>>>>>>>>>>>>>>>>>>>> +    compatible = "ti,lp5024";
>>>>>>>>>>>>>>>>>>>> +    reg = <0x28>;
>>>>>>>>>>>>>>>>>>>> +    #address-cells = <1>;
>>>>>>>>>>>>>>>>>>>> +    #size-cells = <0>;
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +    enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>>>>>>>>>>>>>>>>>>>> +    vled-supply = <&vbatt>;
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +    led@0 {
>>>>>>>>>>>>>>>>>>>> +        reg = <0>;
>>>>>>>>>>>>>>>>>>>> +        led-sources = <1>;
>>>>>>>>>>>>>>>>>>>> +    };
>>>>>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>>>>>> +    led@1 {
>>>>>>>>>>>>>>>>>>>> +        reg = <1>;
>>>>>>>>>>>>>>>>>>>> +        led-sources = <0 6>;
>>>>>>>>>>>>>>>>>>>> +        ti,control-bank;
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Do you really need ti,control-bank? Doesn't led-sources array size
>>>>>>>>>>>>>>>>>>> greater than 1 mean that the node describes control bank?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> That will work too.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Also, does it make sense to have only two LEDs in the bank?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> The array can populate all 7 LEDs in a single node.  I only show 2 here as the example.
>>>>>>>>>>>>>>>>>> See the description above of the led-sources
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> OK, I confused RGB LED modules with banks.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Shouldn't we allow for defining either strings or RGB LED
>>>>>>>>>>>>>>>>> triplets somehow then?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Well that is what this should be doing.  If you define a single LED in LED sources then
>>>>>>>>>>>>>>>> the triplet is controlled via the associated LEDx_brightness register.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> led-sources should map to iouts directly.
>>>>>>>>>>>>>>> So, for RGB LED modules I would expect:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> LED0: led-sources = <0 1 2>;
>>>>>>>>>>>>>>> LED1: led-sources = <3 4 5>;
>>>>>>>>>>>>>>> LED2: led-sources = <6 7 8>;
>>>>>>>>>>>>>>> and so on.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> for banks:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Bank A with iouts 0,3,6,9: led-sources<0 3 6 9>;
>>>>>>>>>>>>>>> Bank B with iouts 2,4,10:  led-sources<2 4 10>;
>>>>>>>>>>>>>>> Bank C with iouts 5,8,11,14,17: led-sources<5 8 11 14 17>;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Ok the led-sources would need to be different then this as I don't define the sources for banks.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> The led-sources for the banks and the individual groups will have different meanings within the same
>>>>>>>>>>>>>> document.  I was attempting to keep the led-sources mapped to the LEDx_brightness registers as opposed to
>>>>>>>>>>>>>> the hardware outputs since the RGB LEDs are controlled and grouped by a single brightness register and if banked then
>>>>>>>>>>>>>> it would be controlled by the bank brightness register.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Describing these in the DT seems wrought with potential issues as the data sheet defines what outputs map to what bank and LED
>>>>>>>>>>>>>> registers.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Yes, that's why I mentioned the need for validation of led-sources.
>>>>>>>>>>>>> But they have to be iouts. This property was introduced specifically
>>>>>>>>>>>>> for such purposes.
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Yes Pavel also mentioned that as well.
>>>>>>>>>>>>
>>>>>>>>>>>> I will look into validating the sources.  But there will be no mapping of the sources to the output that is done
>>>>>>>>>>>> in the hardware.  This would just be a data sheet mapping since the outputs are not configurable.
>>>>>>>>>>>
>>>>>>>>>>> Hmm, isn't the mapping defined in the hardware via LED_CONFIG0 register?
>>>>>>>>>>> I have an impression that it defines whether LED belongs to an RGB LED
>>>>>>>>>>> module or to a bank. Basing on that I created my DT example above.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Yes so if you turn on the bank control for LED0 and LED1 then
>>>>>>>>>> out 0, 3 are mapped to BANK A
>>>>>>>>>> out 1, 4 are mapped to BANK B
>>>>>>>>>
>>>>>>>>> Just noticed that I made a mistake in my example, it should have been:
>>>>>>>>>
>>>>>>>>> Bank B with iouts 1,4,10:  led-sources<1 4 10>;
>>>>>>>>>
>>>>>>>>>> out 2, 5 are mapped to BANK C
>>>>>>>>>
>>>>>>>>> Correct.
>>>>>>>>>
>>>>>>>>>> All done automatically in the hardware and the LED0_BRIGHTNESS and LED1_BRIGHTNESS registers have no affect on the brightness
>>>>>>>>>
>>>>>>>>> That's right.
>>>>>>>>>
>>>>>>>>>> If we grouped the LEDs into a bank the led-sources would look more like this
>>>>>>>>>> led-sources = < 0 1 2 3 4 5 >;
>>>>>>>>>
>>>>>>>>> Why? This would be a mix of three banks. Like you listed above.
>>>>>>>>> I'm still interpreting led-sources elements as iout identifiers.
>>>>>>>>>
>>>>>>>>
>>>>>>>> I am as well but as I tried to explain that if you define OUT0 as bank controlled then OUT1 and OUT2 are also bank controlled
>>>>>>>> within the hardware.  We have no control of that.  If BIT(0) and BIT(1) are set in the LED_CONFIG0 register then OUT0, 1, 2, 3, 4 and 5 are all bank controlled.
>>>>>>>
>>>>>>> There is naming conflict I noticed just now - LEDn_BANK_EN bits
>>>>>>> in LED_CONFIG0 register enable RGB LED modules, and not BANKs (A,B,C).
>>>>>>>
>>>>>>>> These OUTPUTs will appear as a single RGB LED grouping.
>>>>>>>
>>>>>>> Single? W would rather expect that we get two RGB LED modules, whose
>>>>>>> brightness will be controlled via LED0_BRIGHTNESS and LED1_BRIGHTNESS
>>>>>>> registers respectively.
>>>>>>>
>>>>>>>>>> ti,control-bank; // But this can be omitted as led-sources is greater then 3
>>>>>>>>>>
>>>>>>>>>> non-banked case would be
>>>>>>>>>> led-sources = < 0 1 2 >;
>>>>>>>>>
>>>>>>>>> Agreed here. It would be LED0 RGB LED module.
>>>>>>>>>> But the actual OUT numbers don't matter in the bank case unless we do the validation.  There would need to be an algorithim
>>>>>>>>>> that translates these output to the correct LEDx register and CONFIG0 bits.  Basically if OUT0 is mapped to the bank then OUT1 and OUT2
>>>>>>>>>> are inherently mapped to the bank.
>>>>>>>>>
>>>>>>>>> To three separate banks, right?
>>>>>>>>> OUT0 - bank A, OUT1 - bank B, OUT2 - bank C.
>>>>>>>>
>>>>>>>> Yes but there is no BANK output pin just like there is no dedicated LEDn output pin.  The banks are grouped internally to the device
>>>>>>>> so again if OUT0 and OUT3 are defined as banked then 1, 2, 4, and 5 are all mapped to the bank.  1 BANK brightness register and 3 bank
>>>>>>>> color adjustment registers.
>>>>>>>
>>>>>>> Here as above, I would expect two separate banks - LED0 and LED1.
>>>>>>> Moreover - not 3 color adjustment registers, but six - one per iout:
>>>>>>> OUT0_COLOR to OUT5_COLOR.
>>>>>>>
>>>>>>
>>>>>> When the LEDs are banked the banked LEDs are controlled by the bank registers not the LEDx registers
>>>>>> so you should only see 3 color adjustments on the banked LEDs.
>>>>>>
>>>>>>>>>> They cannot be separated so the device theoretically treats the RGB group as a single LED.  And
>>>>>>>>>> when banked it treats the groups of RGBs that are defined as a single LED.
>>>>>>>>>>
>>>>>>>>>> This is why it was easier use the LEDx out as the virtual out as we only need to define the group number(s) that are controled by the
>>>>>>>>>> LED file presented to the user space.
>>>>>>>>>
>>>>>>>>> I suspect there is logical clash here due to interpreting
>>>>>>>>> led-sources elements as iouts in one case and LEDn modules
>>>>>>>>> in the other case.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yes.  When the RGBs are banked you have to think of them as a single RGB LED cluster and not as separate RGB LED clusters.
>>>>>>>
>>>>>>> We have RGB LED modules (enabled with LEDn_Bank_EN bits) and three
>>>>>>> banks (A,B,C), which are enabled by default, am I right?
>>>>>>
>>>>>> No.  Independent LED modules are enabled by default.  You have to explicitly enable the banks.
>>>>>>
>>>>>>>
>>>>>>> Bank A iouts: 0, 3 ,6, 9, 12, 15
>>>>>>> Bank B iouts: 1, 4, 7, 10, 13, 16
>>>>>>> Bank C iouts: 2, 5, 8, 11, 14, 17
>>>>>>>
>>>>>>> When RGB LED module is enabled (via LEDn_Bank_EN bit),
>>>>>>> the BANK_{A.B,C}_COLOR and BANK_BRIGHTNESS registers
>>>>>>> lose control over related IOUTs in favour of LEDn_BRIGHTNESS and
>>>>>>> related OUTn_COLOR registers. Is it correct?
>>>>>>
>>>>>> No it is the opposite.  When the bit is enabled LED banking is enabled and the BANK brightness and color registers over
>>>>>> ride the LEDx color and brightness registers.
>>>>>>
>>>>>> Default is independent control of the RGB via the LEDx color and brightness registers.
>>>>>>
>>>>>>>
>>>>>>>> As you know the brightness is controlled by the single BANK_BRIGHTNESS register.  So identifying each output in the led-sources is
>>>>>>>> misleading as the hardware does this all on the chip.  This is why I just mapped each output to the Virtual LEDx module.
>>>>>>>
>>>>>>> Ekhm, I messed something here.
>>>>>>>
>>>>>>> So for this I would define a single LED class device.
>>>>>>> Related DT node would not need led-sources at all,
>>>>>>> but only ti,control-bank. The semantics would be:
>>>>>>> controls all iouts not taken by RGB LED modules.
>>>>>>>
>>>>>>
>>>>>> Hmm.  I guess I will put that on hold until you read the responses.  I am not sure that would work or
>>>>>> that would be really clean.  I still believe that mapping led-sources to the LEDx module number is the cleanest
>>>>>> simplest solution since the driver cannot inter mix different outputs for enablement.
>>>>>
>>>>> I've read the doc again more carefully and hopefully I finally have
>>>>> proper understanding. Let's check it.
>>>>>
>>>>> 1. On reset LED_CONFIG0 bits are zeroed, which means
>>>>>      LEDn module independent control mode.
>>>>> 2. LEDn modules (i.e. IOUT triplets) are controlled independently,
>>>>>      with use of LEDn_BRIGHTNESS registers, and each IOUT color can
>>>>>      be adjusted using OUTn_CONTROL registers.
>>>>> 3. LEDn_Bank_EN bits, when set to 1, assign given RGB LED module
>>>>>      to one global bank, controlled via BANK_BRIGHTNESS and BANK_n_COLOR
>>>>>      registers.
>>>>>
>>>>> Having that, I'd see led-sources definitions as follows
>>>>> (led-sources element is IOUT identifier)
>>>>>
>>>>> 1.
>>>>>
>>>>> - LED0, LED1, LED2, LED3 modules controlled by separate
>>>>>     LED class devices
>>>>>
>>>>> led-sources = <0 1 2>   // LED0
>>>>> led-sources = <3 4 5>   // LED1
>>>>> led-sources = <6 7 8>   // LED2
>>>>> led-sources = <9 10 11> // LED3
>>>>>
>>>>> 2.
>>>>>
>>>>> - LED0 and LED3 modules assigned to the bank, and controlled
>>>>>     by one LED class device,
>>>>> - LED1 and LED2 modules controlled by separate LED class devices
>>>>>
>>>>> led-sources = <0 1 2 9 10 11> // Bank with LED0 and LED3
>>>>> led-sources = <3 4 5>         // LED1
>>>>> led-sources = <6 7 8>         // LED2
>>>>>
>>>>>
>>>>> So now I see your point. It would be indeed easier
>>>>> to switch to LEDn module identifiers for led-sources
>>>>> elements. With that the definitions would look like
>>>>> this:
>>>>>
>>>>>
>>>>> 1.
>>>>>
>>>>> - LED0, LED1, LED2, LED3 modules controlled by separate
>>>>>     LED class devices
>>>>>
>>>>> led-sources = <0>   // LED0
>>>>> led-sources = <1>   // LED1
>>>>> led-sources = <2>   // LED2
>>>>> led-sources = <3>   // LED3
>>>>>
>>>>> 2.
>>>>>
>>>>> - LED0 and LED3 modules assigned to the bank, and controlled
>>>>>     by one LED class device,
>>>>> - LED1 and LED2 modules controlled by separate LED class devices
>>>>>
>>>>> led-sources = <0 3> // Bank with LED0 and LED3
>>>>> led-sources = <1>   // LED1
>>>>> led-sources = <2>   // LED2
>>>>>
>>>>
>>>> This is exactly how I submitted the code.
>>>>
>>>>>
>>>>> But, I don't think use of led-sources is justified in
>>>>> this case. I propose to introduce device specific properties:
>>>>>
>>>>> ti,led-module and ti,led-bank
>>>>>
>>>>> With that we would have:
>>>>>
>>>>> ti,led-bank = <0 3>   // Bank with LED0 and LED3 modules
>>>>> ti,led-module = <1>   // LED1
>>>>> ti.led-module = <2>   // LED2
>>>>>
>>>>
>>>> We are now aligned.  I can change the led-sources to the TI specific if there are no further objections.
>>>> In doing this I can eliminate the ti,control-bank property.
>>>>
>>>>>
>>>>>>> I would also add Table 1 contents (Bank Number and LED Number
>>>>>>> Assignment) to the DT bindings.
>>>>>>>
>>>>>>
>>>>>> Should I add that to the DT binding or reference the data sheet table since this driver will support 4 different devices
>>>>>> with varying number of outputs from 18-36.
>>>>>
>>>>> My first thought was to show full table, but four different
>>>>> mappings would add too much noise. So the reference to the data
>>>>> sheet should suffice.
>>>>>
>>>>
>>>> OK
>>>>
>>>> One last question I am going to add the LP5036 and 30 which have the same technology but slightly different register maps.
>>>> Should I rename the driver to LP5036.c as the 30, 24 and 18 would technically be subsets?
>>>
>>> How about leds-lp50xx.c ? You can also create a library like
>>> drivers/leds/leds-lp55xx-common.c if that would simplify the code.
>>>
>>
>> A library would be overkill.
>> Is it just the DT that we don't want to use wild cards in naming?
> 
> DT is for concrete board and cpu, so it doesn't make sense to
> use wildcards in *.dts file names.
> 
>> leds-lp50xx.c is a fine name to me.
> 
> Apart of that, I've been also mulling over if we shouldn't go for single
> "color" sysfs file for setting r,g,b components at one go.
> I don't see any downsides. There is no risk that number of elements will
> grow, and the benefit will be an atomic way of setting color - the
> feature people are looking for. Vesa was mentioning the case where lack
> of it had been a real problem [0].
> 

Well thats what I did and have it working.  I was going to submit v2 today after I write the documentation.

I basically exposed a "hue" file that takes in a 24 bit R,G,B value and sets the registers accordingly.

I figured hue would be good as that may be the same ABI we have when the RGB framework comes in.

The change over would be transparent to the past users.

Dan

> Let's check the usability of such interface.
> 
> [0] https://lkml.org/lkml/2019/1/4/519
> 


-- 
------------------
Dan Murphy

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-14 20:14                                         ` Dan Murphy
@ 2019-01-14 20:28                                           ` Jacek Anaszewski
  2019-01-14 20:29                                             ` Dan Murphy
  0 siblings, 1 reply; 106+ messages in thread
From: Jacek Anaszewski @ 2019-01-14 20:28 UTC (permalink / raw)
  To: Dan Murphy, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Dan,

On 1/14/19 9:14 PM, Dan Murphy wrote:
[...]
>>>>> One last question I am going to add the LP5036 and 30 which have the same technology but slightly different register maps.
>>>>> Should I rename the driver to LP5036.c as the 30, 24 and 18 would technically be subsets?
>>>>
>>>> How about leds-lp50xx.c ? You can also create a library like
>>>> drivers/leds/leds-lp55xx-common.c if that would simplify the code.
>>>>
>>>
>>> A library would be overkill.
>>> Is it just the DT that we don't want to use wild cards in naming?
>>
>> DT is for concrete board and cpu, so it doesn't make sense to
>> use wildcards in *.dts file names.
>>
>>> leds-lp50xx.c is a fine name to me.
>>
>> Apart of that, I've been also mulling over if we shouldn't go for single
>> "color" sysfs file for setting r,g,b components at one go.
>> I don't see any downsides. There is no risk that number of elements will
>> grow, and the benefit will be an atomic way of setting color - the
>> feature people are looking for. Vesa was mentioning the case where lack
>> of it had been a real problem [0].
>>
> 
> Well thats what I did and have it working.  I was going to submit v2 today after I write the documentation.
> 
> I basically exposed a "hue" file that takes in a 24 bit R,G,B value and sets the registers accordingly.
> 
> I figured hue would be good as that may be the same ABI we have when the RGB framework comes in.
> 
> The change over would be transparent to the past users.

I'd prefer "color" over "hue". The latter implies HSV color space, which
was the first thing that came to my mind when reading your message.

-- 
Best regards,
Jacek Anaszewski

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

* Re: [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver
  2019-01-14 20:28                                           ` Jacek Anaszewski
@ 2019-01-14 20:29                                             ` Dan Murphy
  0 siblings, 0 replies; 106+ messages in thread
From: Dan Murphy @ 2019-01-14 20:29 UTC (permalink / raw)
  To: Jacek Anaszewski, robh+dt, pavel; +Cc: devicetree, linux-kernel, linux-leds

Jacek

On 1/14/19 2:28 PM, Jacek Anaszewski wrote:
> Dan,
> 
> On 1/14/19 9:14 PM, Dan Murphy wrote:
> [...]
>>>>>> One last question I am going to add the LP5036 and 30 which have the same technology but slightly different register maps.
>>>>>> Should I rename the driver to LP5036.c as the 30, 24 and 18 would technically be subsets?
>>>>>
>>>>> How about leds-lp50xx.c ? You can also create a library like
>>>>> drivers/leds/leds-lp55xx-common.c if that would simplify the code.
>>>>>
>>>>
>>>> A library would be overkill.
>>>> Is it just the DT that we don't want to use wild cards in naming?
>>>
>>> DT is for concrete board and cpu, so it doesn't make sense to
>>> use wildcards in *.dts file names.
>>>
>>>> leds-lp50xx.c is a fine name to me.
>>>
>>> Apart of that, I've been also mulling over if we shouldn't go for single
>>> "color" sysfs file for setting r,g,b components at one go.
>>> I don't see any downsides. There is no risk that number of elements will
>>> grow, and the benefit will be an atomic way of setting color - the
>>> feature people are looking for. Vesa was mentioning the case where lack
>>> of it had been a real problem [0].
>>>
>>
>> Well thats what I did and have it working.  I was going to submit v2 today after I write the documentation.
>>
>> I basically exposed a "hue" file that takes in a 24 bit R,G,B value and sets the registers accordingly.
>>
>> I figured hue would be good as that may be the same ABI we have when the RGB framework comes in.
>>
>> The change over would be transparent to the past users.
> 
> I'd prefer "color" over "hue". The latter implies HSV color space, which
> was the first thing that came to my mind when reading your message.
> 

Done

Dan
-- 
------------------
Dan Murphy

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

* Backlight in motorola Droid 4
  2018-12-19 16:26 [PATCH 0/2] LP5024/18 LED introduction Dan Murphy
  2018-12-19 16:26 ` [PATCH 1/2] dt: bindings: lp5024: Introduce the lp5024 and lp5018 RGB driver Dan Murphy
  2018-12-19 16:26 ` [PATCH 2/2] leds: lp5024: Add the LP5024/18 RGB LED driver Dan Murphy
@ 2019-07-22 20:59 ` Pavel Machek
  2019-07-23 15:53   ` Dan Murphy
  2 siblings, 1 reply; 106+ messages in thread
From: Pavel Machek @ 2019-07-22 20:59 UTC (permalink / raw)
  To: Dan Murphy, linux-omap, tony, sre, nekit1000, mpartap, merlijn
  Cc: jacek.anaszewski, linux-kernel, linux-leds

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

Hi!

So now the backlight LED can be controlled. Good. (And thanks!)

But I seem to remember that backlight had range from "is it really on?"
to "very bright"; now it seems to have range from "bright" to "very
bright".

Any ideas what goes on there?

Thanks,
									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] 106+ messages in thread

* Re: Backlight in motorola Droid 4
  2019-07-22 20:59 ` Backlight in motorola Droid 4 Pavel Machek
@ 2019-07-23 15:53   ` Dan Murphy
  2019-07-24  8:22     ` Pavel Machek
  2019-07-24 12:45     ` Pavel Machek
  0 siblings, 2 replies; 106+ messages in thread
From: Dan Murphy @ 2019-07-23 15:53 UTC (permalink / raw)
  To: Pavel Machek, linux-omap, tony, sre, nekit1000, mpartap, merlijn
  Cc: jacek.anaszewski, linux-kernel, linux-leds

Pavel

On 7/22/19 3:59 PM, Pavel Machek wrote:
> Hi!
>
> So now the backlight LED can be controlled. Good. (And thanks!)
>
> But I seem to remember that backlight had range from "is it really on?"
> to "very bright"; now it seems to have range from "bright" to "very
> bright".
>
> Any ideas what goes on there?

In the LM3552 driver we are changing the Full scale brightness registers 
for the

specific control bank.

#define LM3532_REG_CTRL_A_BRT    0x17
#define LM3532_REG_CTRL_B_BRT    0x19
#define LM3532_REG_CTRL_C_BRT    0x1b

In the ti-lmu code the ALS zones were being modified not the control 
bank brightness.

#define LM3532_REG_BRT_A            0x70    /* zone 0 */
#define LM3532_REG_BRT_B            0x76    /* zone 1 */
#define LM3532_REG_BRT_C            0x7C    /* zone 2 */

Not sure how the ALS is attached in the system if it reports to the host 
and the host manages

the back light or if the the ALS is connected directly to the LM3532.

Maybe the ALS zone targets need to be updated to allow a fuller range.  
The LM3532 may be stuck

in a certain zone.

Probably should set up the ALS properties in the device tree.

Dan

> Thanks,
> 									Pavel
>

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

* Re: Backlight in motorola Droid 4
  2019-07-23 15:53   ` Dan Murphy
@ 2019-07-24  8:22     ` Pavel Machek
  2019-07-24 12:45     ` Pavel Machek
  1 sibling, 0 replies; 106+ messages in thread
From: Pavel Machek @ 2019-07-24  8:22 UTC (permalink / raw)
  To: Dan Murphy
  Cc: linux-omap, tony, sre, nekit1000, mpartap, merlijn,
	jacek.anaszewski, linux-kernel, linux-leds

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

On Tue 2019-07-23 10:53:16, Dan Murphy wrote:
> Pavel
> 
> On 7/22/19 3:59 PM, Pavel Machek wrote:
> >Hi!
> >
> >So now the backlight LED can be controlled. Good. (And thanks!)
> >
> >But I seem to remember that backlight had range from "is it really on?"
> >to "very bright"; now it seems to have range from "bright" to "very
> >bright".
> >
> >Any ideas what goes on there?
> 
> In the LM3552 driver we are changing the Full scale brightness registers for
> the
> 
> specific control bank.
> 
> #define LM3532_REG_CTRL_A_BRT    0x17
> #define LM3532_REG_CTRL_B_BRT    0x19
> #define LM3532_REG_CTRL_C_BRT    0x1b

Yep, and those registers are 5-bit linear...

> In the ti-lmu code the ALS zones were being modified not the control bank
> brightness.
> 
> #define LM3532_REG_BRT_A            0x70    /* zone 0 */
> #define LM3532_REG_BRT_B            0x76    /* zone 1 */
> #define LM3532_REG_BRT_C            0x7C    /* zone 2 */

...while these allow 14-bits of control.

That explains very limited range of backlight control.

Do you have any plans to change that?

Best regards,
									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] 106+ messages in thread

* Re: Backlight in motorola Droid 4
  2019-07-23 15:53   ` Dan Murphy
  2019-07-24  8:22     ` Pavel Machek
@ 2019-07-24 12:45     ` Pavel Machek
  2019-07-24 15:10       ` Dan Murphy
  2019-07-24 15:22       ` Dan Murphy
  1 sibling, 2 replies; 106+ messages in thread
From: Pavel Machek @ 2019-07-24 12:45 UTC (permalink / raw)
  To: Dan Murphy
  Cc: linux-omap, tony, sre, nekit1000, mpartap, merlijn,
	jacek.anaszewski, linux-kernel, linux-leds

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

Hi!

> >So now the backlight LED can be controlled. Good. (And thanks!)
> >
> >But I seem to remember that backlight had range from "is it really on?"
> >to "very bright"; now it seems to have range from "bright" to "very
> >bright".
> >
> >Any ideas what goes on there?
> 
> In the LM3552 driver we are changing the Full scale brightness registers for
> the
> 
> specific control bank.
> 
> #define LM3532_REG_CTRL_A_BRT    0x17
> #define LM3532_REG_CTRL_B_BRT    0x19
> #define LM3532_REG_CTRL_C_BRT    0x1b
> 
> In the ti-lmu code the ALS zones were being modified not the control bank
> brightness.
> 
> #define LM3532_REG_BRT_A            0x70    /* zone 0 */
> #define LM3532_REG_BRT_B            0x76