* [PATCH v2 1/2] dt-bindings: leds: Add binding for spi-byte LED. @ 2019-05-05 12:52 oss 2019-05-05 12:52 ` [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver oss 0 siblings, 1 reply; 8+ messages in thread From: oss @ 2019-05-05 12:52 UTC (permalink / raw) To: linux-leds, devicetree, Jacek Anaszewski, Pavel Machek Cc: Dan Murphy, Rob Herring, Mark Rutland, Christian Mauderer From: Christian Mauderer <oss@c-mauderer.de> This patch adds the binding documentation for a simple SPI based LED controller which use only one byte for setting the brightness. Signed-off-by: Christian Mauderer <oss@c-mauderer.de> --- Changes compared to v1: - rename ubnt-spi to leds-spi-byte - rename "ubnt-spi,off_bright" and "ubnt-spi,max_bright" to "leds-spi-byte,off-value" and "leds-spi-byte,max-value" and mark them required - rename led-controller node to "led-controller" - extend description - remove SPI controller - use "white:status" for the example label .../bindings/leds/leds-spi-byte.txt | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/leds-spi-byte.txt diff --git a/Documentation/devicetree/bindings/leds/leds-spi-byte.txt b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt new file mode 100644 index 000000000000..1dd6ab03a56d --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-spi-byte.txt @@ -0,0 +1,47 @@ +* Single Byte SPI LED Device Driver. + +The driver can be used for controllers with a very simple SPI protocol: Only one +byte will be sent. The value of the byte can be any value between the off-value +and max-value defined in the properties. + +One example where the driver can be used is the controller in Ubiquiti airCube +ISP devices. That LED controller is based on a 8 bit microcontroller (SONiX +8F26E611LA) that has been programmed to control the single LED of the device. +The controller supports four modes depending on the highest two bits in a byte: +One setting for brightness, the other three provide different blink patterns. +With the leds-spi-byte driver a basic support for the brightness mode of that +controller can be easily achieved by setting the minimum and maximum to the +brightness modes minimum and maximum byte value. + +Required properties: +- compatible: Should be "leds-spi-byte". + +Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt +apply. In particular, "reg" and "spi-max-frequency" properties must be given. + +The driver currently only supports one LED. The properties of the LED are +configured in a sub-node in the device node. + +LED sub-node properties: +- label: + see Documentation/devicetree/bindings/leds/common.txt +- leds-spi-byte,off-value: + The SPI byte value that should be sent to switch the LED off. Has to be + smaller than max-value. Range: 0 to 254. +- leds-spi-byte,max-value: + The SPI byte value that should be sent to set the LED to the maximum + brightness. Has to be bigger than off-value. Range: 1 to 255. + +Example: + +led-controller@0 { + compatible = "leds-spi-byte"; + reg = <0>; + spi-max-frequency = <100000>; + + led { + label = "white:status"; + leds-spi-byte,off-value = /bits/ 8 <0>; + leds-spi-byte,max-value = /bits/ 8 <63>; + }; +}; -- 2.21.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver 2019-05-05 12:52 [PATCH v2 1/2] dt-bindings: leds: Add binding for spi-byte LED oss @ 2019-05-05 12:52 ` oss 2019-05-05 14:48 ` Jacek Anaszewski 0 siblings, 1 reply; 8+ messages in thread From: oss @ 2019-05-05 12:52 UTC (permalink / raw) To: linux-leds, devicetree, Jacek Anaszewski, Pavel Machek Cc: Dan Murphy, Rob Herring, Mark Rutland, Christian Mauderer From: Christian Mauderer <oss@c-mauderer.de> This driver adds support for simple SPI based LED controller which use only one byte for setting the brightness. Signed-off-by: Christian Mauderer <oss@c-mauderer.de> --- Changes compared to v1: - rename ubnt-spi to leds-spi-byte - rework probe to get all parameters before allocating anything -> error checks all collected together and initializing all fields of the device structure is more obvious - fix some unsteady indentations during variable declaration - rework comment with protocol explanation - handle case of off_bright > max_bright - fix spelling in commit message - mutex_destroy in remove - change label to use either use the given one without a prefix or a default one NOTE: Should the label be a mandatory parameter instead of the default label? drivers/leds/Kconfig | 12 ++++ drivers/leds/Makefile | 1 + drivers/leds/leds-spi-byte.c | 133 +++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 drivers/leds/leds-spi-byte.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index a72f97fca57b..0866c55e8004 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -766,6 +766,18 @@ config LEDS_NIC78BX To compile this driver as a module, choose M here: the module will be called leds-nic78bx. +config LEDS_SPI_BYTE + tristate "LED support for SPI LED controller with a single byte" + depends on LEDS_CLASS + depends on SPI + depends on OF + help + This option enables support for LED controller which use a single byte + for controlling the brightness. The minimum and maximum value of the + byte can be configured via a device tree. The driver can be used for + example for the microcontroller based LED controller in the Ubiquiti + airCube ISP devices. + comment "LED Triggers" source "drivers/leds/trigger/Kconfig" diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 4c1b0054f379..1786d7e2c236 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -75,6 +75,7 @@ obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o obj-$(CONFIG_LEDS_MLXCPLD) += leds-mlxcpld.o obj-$(CONFIG_LEDS_MLXREG) += leds-mlxreg.o obj-$(CONFIG_LEDS_NIC78BX) += leds-nic78bx.o +obj-$(CONFIG_LEDS_SPI_BYTE) += leds-spi-byte.o obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c new file mode 100644 index 000000000000..19a68bce1a7c --- /dev/null +++ b/drivers/leds/leds-spi-byte.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de> + +/* + * The driver can be used for controllers with a very simple SPI protocol: Only + * one byte between an off and a max value (defined by devicetree) will be sent. + */ + +#include <linux/leds.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/spi/spi.h> +#include <linux/mutex.h> +#include <uapi/linux/uleds.h> + +struct spi_byte_led { + struct led_classdev ldev; + struct spi_device *spi; + char name[LED_MAX_NAME_SIZE]; + struct mutex mutex; + u8 off_value; + u8 max_value; +}; + +static int spi_byte_brightness_set_blocking(struct led_classdev *dev, + enum led_brightness brightness) +{ + struct spi_byte_led *led = container_of(dev, struct spi_byte_led, ldev); + u8 value; + int ret; + + value = (u8) brightness + led->off_value; + + mutex_lock(&led->mutex); + ret = spi_write(led->spi, &value, sizeof(value)); + mutex_unlock(&led->mutex); + + return ret; +} + +static int spi_byte_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct device_node *child; + struct spi_byte_led *led; + int ret; + const char *default_name = "leds-spi-byte::"; + const char *name; + u8 off_value; + u8 max_value; + + if (!dev->of_node) + return -ENODEV; + + if (of_get_child_count(dev->of_node) != 1) { + dev_err(dev, "Device must have exactly one LED sub-node."); + return -EINVAL; + } + child = of_get_next_child(dev->of_node, NULL); + + ret = of_property_read_string(child, "label", &name); + if (ret != 0) + name = default_name; + + ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value); + if (ret != 0) { + dev_err(dev, "LED node needs a leds-spi-byte,off-value."); + return -EINVAL; + } + + ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value); + if (ret != 0) { + dev_err(dev, "LED node needs a leds-spi-byte,max-value."); + return -EINVAL; + } + + if (off_value >= max_value) { + dev_err(dev, "off-value has to be smaller than max-value."); + return -EINVAL; + } + + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); + if (!led) + return -ENOMEM; + + led->spi = spi; + strlcpy(led->name, name, sizeof(led->name)); + mutex_init(&led->mutex); + led->off_value = off_value; + led->max_value = max_value; + led->ldev.name = led->name; + led->ldev.brightness = LED_OFF; + led->ldev.max_brightness = led->max_value - led->off_value; + led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking; + ret = led_classdev_register(&spi->dev, &led->ldev); + if (ret >= 0) + spi_set_drvdata(spi, led); + + return ret; +} + +static int spi_byte_remove(struct spi_device *spi) +{ + struct spi_byte_led *led = spi_get_drvdata(spi); + + led_classdev_unregister(&led->ldev); + mutex_destroy(&led->mutex); + + return 0; +} + +static const struct of_device_id spi_byte_dt_ids[] = { + { .compatible = "leds-spi-byte", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, spi_byte_dt_ids); + +static struct spi_driver spi_byte_driver = { + .probe = spi_byte_probe, + .remove = spi_byte_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = spi_byte_dt_ids, + }, +}; + +module_spi_driver(spi_byte_driver); + +MODULE_AUTHOR("Christian Mauderer <oss@c-mauderer.de>"); +MODULE_DESCRIPTION("single byte SPI LED driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:leds-spi-byte"); -- 2.21.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver 2019-05-05 12:52 ` [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver oss @ 2019-05-05 14:48 ` Jacek Anaszewski 2019-05-05 14:55 ` Christian Mauderer 2019-05-05 20:12 ` Pavel Machek 0 siblings, 2 replies; 8+ messages in thread From: Jacek Anaszewski @ 2019-05-05 14:48 UTC (permalink / raw) To: oss, linux-leds, devicetree, Pavel Machek Cc: Dan Murphy, Rob Herring, Mark Rutland Hi Christian, Thank you for the update. I have some trivial nits, please refer below. On 5/5/19 2:52 PM, oss@c-mauderer.de wrote: > From: Christian Mauderer <oss@c-mauderer.de> > > This driver adds support for simple SPI based LED controller which use > only one byte for setting the brightness. > > Signed-off-by: Christian Mauderer <oss@c-mauderer.de> > --- > > Changes compared to v1: > - rename ubnt-spi to leds-spi-byte > - rework probe to get all parameters before allocating anything -> error checks > all collected together and initializing all fields of the device structure is > more obvious > - fix some unsteady indentations during variable declaration > - rework comment with protocol explanation > - handle case of off_bright > max_bright > - fix spelling in commit message > - mutex_destroy in remove > - change label to use either use the given one without a prefix or a default one > NOTE: Should the label be a mandatory parameter instead of the default label? > > > drivers/leds/Kconfig | 12 ++++ > drivers/leds/Makefile | 1 + > drivers/leds/leds-spi-byte.c | 133 +++++++++++++++++++++++++++++++++++ > 3 files changed, 146 insertions(+) > create mode 100644 drivers/leds/leds-spi-byte.c > > diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig > index a72f97fca57b..0866c55e8004 100644 > --- a/drivers/leds/Kconfig > +++ b/drivers/leds/Kconfig > @@ -766,6 +766,18 @@ config LEDS_NIC78BX > To compile this driver as a module, choose M here: the module > will be called leds-nic78bx. > > +config LEDS_SPI_BYTE > + tristate "LED support for SPI LED controller with a single byte" > + depends on LEDS_CLASS > + depends on SPI > + depends on OF > + help > + This option enables support for LED controller which use a single byte > + for controlling the brightness. The minimum and maximum value of the > + byte can be configured via a device tree. The driver can be used for > + example for the microcontroller based LED controller in the Ubiquiti > + airCube ISP devices. > + > comment "LED Triggers" > source "drivers/leds/trigger/Kconfig" > > diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile > index 4c1b0054f379..1786d7e2c236 100644 > --- a/drivers/leds/Makefile > +++ b/drivers/leds/Makefile > @@ -75,6 +75,7 @@ obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o > obj-$(CONFIG_LEDS_MLXCPLD) += leds-mlxcpld.o > obj-$(CONFIG_LEDS_MLXREG) += leds-mlxreg.o > obj-$(CONFIG_LEDS_NIC78BX) += leds-nic78bx.o > +obj-$(CONFIG_LEDS_SPI_BYTE) += leds-spi-byte.o > obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o > obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o > obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o > diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c > new file mode 100644 > index 000000000000..19a68bce1a7c > --- /dev/null > +++ b/drivers/leds/leds-spi-byte.c > @@ -0,0 +1,133 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de> > + > +/* > + * The driver can be used for controllers with a very simple SPI protocol: Only > + * one byte between an off and a max value (defined by devicetree) will be sent. > + */ > + > +#include <linux/leds.h> > +#include <linux/module.h> > +#include <linux/of_device.h> > +#include <linux/spi/spi.h> > +#include <linux/mutex.h> > +#include <uapi/linux/uleds.h> > + > +struct spi_byte_led { > + struct led_classdev ldev; > + struct spi_device *spi; > + char name[LED_MAX_NAME_SIZE]; > + struct mutex mutex; > + u8 off_value; > + u8 max_value; > +}; > + > +static int spi_byte_brightness_set_blocking(struct led_classdev *dev, > + enum led_brightness brightness) > +{ > + struct spi_byte_led *led = container_of(dev, struct spi_byte_led, ldev); > + u8 value; > + int ret; > + > + value = (u8) brightness + led->off_value; > + > + mutex_lock(&led->mutex); > + ret = spi_write(led->spi, &value, sizeof(value)); > + mutex_unlock(&led->mutex); > + > + return ret; > +} > + > +static int spi_byte_probe(struct spi_device *spi) > +{ > + struct device *dev = &spi->dev; > + struct device_node *child; > + struct spi_byte_led *led; > + int ret; > + const char *default_name = "leds-spi-byte::"; > + const char *name; > + u8 off_value; > + u8 max_value; > + > + if (!dev->of_node) > + return -ENODEV; > + > + if (of_get_child_count(dev->of_node) != 1) { > + dev_err(dev, "Device must have exactly one LED sub-node."); > + return -EINVAL; > + } > + child = of_get_next_child(dev->of_node, NULL); > + > + ret = of_property_read_string(child, "label", &name); > + if (ret != 0) It is more customary to have "if (ret)" in such cases. Applies to all occurrences below. > + name = default_name; > + > + ret = of_property_read_u8(child, "leds-spi-byte,off-value", &off_value); > + if (ret != 0) { > + dev_err(dev, "LED node needs a leds-spi-byte,off-value."); > + return -EINVAL; > + } > + > + ret = of_property_read_u8(child, "leds-spi-byte,max-value", &max_value); > + if (ret != 0) { > + dev_err(dev, "LED node needs a leds-spi-byte,max-value."); > + return -EINVAL; > + } > + > + if (off_value >= max_value) { > + dev_err(dev, "off-value has to be smaller than max-value."); > + return -EINVAL; > + } > + > + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); > + if (!led) > + return -ENOMEM; > + > + led->spi = spi; > + strlcpy(led->name, name, sizeof(led->name)); > + mutex_init(&led->mutex); > + led->off_value = off_value; > + led->max_value = max_value; > + led->ldev.name = led->name; > + led->ldev.brightness = LED_OFF; This line is redundant - already zeroed by kzalloc. > + led->ldev.max_brightness = led->max_value - led->off_value; > + led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking; > + ret = led_classdev_register(&spi->dev, &led->ldev); Please use devm_led_classdev_register(). > + if (ret >= 0) > + spi_set_drvdata(spi, led); This looks quite odd. Please shape it as below: if (ret) return ret spi_set_drvdata(spi, led); > + > + return ret; s/ret/0/ > +} > + > +static int spi_byte_remove(struct spi_device *spi) > +{ > + struct spi_byte_led *led = spi_get_drvdata(spi); > + > + led_classdev_unregister(&led->ldev); > + mutex_destroy(&led->mutex); > + > + return 0; > +} > + > +static const struct of_device_id spi_byte_dt_ids[] = { > + { .compatible = "leds-spi-byte", }, > + {}, > +}; > + > +MODULE_DEVICE_TABLE(of, spi_byte_dt_ids); > + > +static struct spi_driver spi_byte_driver = { > + .probe = spi_byte_probe, > + .remove = spi_byte_remove, > + .driver = { > + .name = KBUILD_MODNAME, > + .of_match_table = spi_byte_dt_ids, > + }, > +}; > + > +module_spi_driver(spi_byte_driver); > + > +MODULE_AUTHOR("Christian Mauderer <oss@c-mauderer.de>"); > +MODULE_DESCRIPTION("single byte SPI LED driver"); > +MODULE_LICENSE("GPL v2"); > +MODULE_ALIAS("spi:leds-spi-byte"); > -- Best regards, Jacek Anaszewski ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver 2019-05-05 14:48 ` Jacek Anaszewski @ 2019-05-05 14:55 ` Christian Mauderer 2019-05-05 20:12 ` Pavel Machek 1 sibling, 0 replies; 8+ messages in thread From: Christian Mauderer @ 2019-05-05 14:55 UTC (permalink / raw) To: Jacek Anaszewski, linux-leds, devicetree, Pavel Machek Cc: Dan Murphy, Rob Herring, Mark Rutland On 05/05/2019 16:48, Jacek Anaszewski wrote: > Hi Christian, > > Thank you for the update. I have some trivial nits, > please refer below. Hello Jacek, thanks for having a look. I don't have problems with the changes and will integrate them into a v3. Sorry for the style nitpicks for example with the (ret != 0). It's different for each project and I haven't written much code with Linux style yet. I'll wait for another few hours in case someone else wants additional changes before posting v3. Best regards Christian > > On 5/5/19 2:52 PM, oss@c-mauderer.de wrote: >> From: Christian Mauderer <oss@c-mauderer.de> >> >> This driver adds support for simple SPI based LED controller which use >> only one byte for setting the brightness. >> >> Signed-off-by: Christian Mauderer <oss@c-mauderer.de> >> --- >> >> Changes compared to v1: >> - rename ubnt-spi to leds-spi-byte >> - rework probe to get all parameters before allocating anything -> >> error checks >> all collected together and initializing all fields of the device >> structure is >> more obvious >> - fix some unsteady indentations during variable declaration >> - rework comment with protocol explanation >> - handle case of off_bright > max_bright >> - fix spelling in commit message >> - mutex_destroy in remove >> - change label to use either use the given one without a prefix or a >> default one >> NOTE: Should the label be a mandatory parameter instead of the >> default label? >> >> >> drivers/leds/Kconfig | 12 ++++ >> drivers/leds/Makefile | 1 + >> drivers/leds/leds-spi-byte.c | 133 +++++++++++++++++++++++++++++++++++ >> 3 files changed, 146 insertions(+) >> create mode 100644 drivers/leds/leds-spi-byte.c >> >> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig >> index a72f97fca57b..0866c55e8004 100644 >> --- a/drivers/leds/Kconfig >> +++ b/drivers/leds/Kconfig >> @@ -766,6 +766,18 @@ config LEDS_NIC78BX >> To compile this driver as a module, choose M here: the module >> will be called leds-nic78bx. >> +config LEDS_SPI_BYTE >> + tristate "LED support for SPI LED controller with a single byte" >> + depends on LEDS_CLASS >> + depends on SPI >> + depends on OF >> + help >> + This option enables support for LED controller which use a >> single byte >> + for controlling the brightness. The minimum and maximum value >> of the >> + byte can be configured via a device tree. The driver can be >> used for >> + example for the microcontroller based LED controller in the >> Ubiquiti >> + airCube ISP devices. >> + >> comment "LED Triggers" >> source "drivers/leds/trigger/Kconfig" >> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile >> index 4c1b0054f379..1786d7e2c236 100644 >> --- a/drivers/leds/Makefile >> +++ b/drivers/leds/Makefile >> @@ -75,6 +75,7 @@ obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o >> obj-$(CONFIG_LEDS_MLXCPLD) += leds-mlxcpld.o >> obj-$(CONFIG_LEDS_MLXREG) += leds-mlxreg.o >> obj-$(CONFIG_LEDS_NIC78BX) += leds-nic78bx.o >> +obj-$(CONFIG_LEDS_SPI_BYTE) += leds-spi-byte.o >> obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o >> obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o >> obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o >> diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c >> new file mode 100644 >> index 000000000000..19a68bce1a7c >> --- /dev/null >> +++ b/drivers/leds/leds-spi-byte.c >> @@ -0,0 +1,133 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +// Copyright (c) 2019 Christian Mauderer <oss@c-mauderer.de> >> + >> +/* >> + * The driver can be used for controllers with a very simple SPI >> protocol: Only >> + * one byte between an off and a max value (defined by devicetree) >> will be sent. >> + */ >> + >> +#include <linux/leds.h> >> +#include <linux/module.h> >> +#include <linux/of_device.h> >> +#include <linux/spi/spi.h> >> +#include <linux/mutex.h> >> +#include <uapi/linux/uleds.h> >> + >> +struct spi_byte_led { >> + struct led_classdev ldev; >> + struct spi_device *spi; >> + char name[LED_MAX_NAME_SIZE]; >> + struct mutex mutex; >> + u8 off_value; >> + u8 max_value; >> +}; >> + >> +static int spi_byte_brightness_set_blocking(struct led_classdev *dev, >> + enum led_brightness brightness) >> +{ >> + struct spi_byte_led *led = container_of(dev, struct spi_byte_led, >> ldev); >> + u8 value; >> + int ret; >> + >> + value = (u8) brightness + led->off_value; >> + >> + mutex_lock(&led->mutex); >> + ret = spi_write(led->spi, &value, sizeof(value)); >> + mutex_unlock(&led->mutex); >> + >> + return ret; >> +} >> + >> +static int spi_byte_probe(struct spi_device *spi) >> +{ >> + struct device *dev = &spi->dev; >> + struct device_node *child; >> + struct spi_byte_led *led; >> + int ret; >> + const char *default_name = "leds-spi-byte::"; >> + const char *name; >> + u8 off_value; >> + u8 max_value; >> + >> + if (!dev->of_node) >> + return -ENODEV; >> + >> + if (of_get_child_count(dev->of_node) != 1) { >> + dev_err(dev, "Device must have exactly one LED sub-node."); >> + return -EINVAL; >> + } >> + child = of_get_next_child(dev->of_node, NULL); >> + >> + ret = of_property_read_string(child, "label", &name); >> + if (ret != 0) > > It is more customary to have "if (ret)" in such cases. > Applies to all occurrences below. > >> + name = default_name; >> + >> + ret = of_property_read_u8(child, "leds-spi-byte,off-value", >> &off_value); >> + if (ret != 0) { >> + dev_err(dev, "LED node needs a leds-spi-byte,off-value."); >> + return -EINVAL; >> + } >> + >> + ret = of_property_read_u8(child, "leds-spi-byte,max-value", >> &max_value); >> + if (ret != 0) { >> + dev_err(dev, "LED node needs a leds-spi-byte,max-value."); >> + return -EINVAL; >> + } >> + >> + if (off_value >= max_value) { >> + dev_err(dev, "off-value has to be smaller than max-value."); >> + return -EINVAL; >> + } >> + >> + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); >> + if (!led) >> + return -ENOMEM; >> + >> + led->spi = spi; >> + strlcpy(led->name, name, sizeof(led->name)); >> + mutex_init(&led->mutex); >> + led->off_value = off_value; >> + led->max_value = max_value; >> + led->ldev.name = led->name; >> + led->ldev.brightness = LED_OFF; > > This line is redundant - already zeroed by kzalloc. > >> + led->ldev.max_brightness = led->max_value - led->off_value; >> + led->ldev.brightness_set_blocking = >> spi_byte_brightness_set_blocking; >> + ret = led_classdev_register(&spi->dev, &led->ldev); > > Please use devm_led_classdev_register(). > >> + if (ret >= 0) >> + spi_set_drvdata(spi, led); > > This looks quite odd. Please shape it as below: > > if (ret) > return ret > > spi_set_drvdata(spi, led); > >> + >> + return ret; > > s/ret/0/ > >> +} >> + >> +static int spi_byte_remove(struct spi_device *spi) >> +{ >> + struct spi_byte_led *led = spi_get_drvdata(spi); >> + >> + led_classdev_unregister(&led->ldev); >> + mutex_destroy(&led->mutex); >> + >> + return 0; >> +} >> + >> +static const struct of_device_id spi_byte_dt_ids[] = { >> + { .compatible = "leds-spi-byte", }, >> + {}, >> +}; >> + >> +MODULE_DEVICE_TABLE(of, spi_byte_dt_ids); >> + >> +static struct spi_driver spi_byte_driver = { >> + .probe = spi_byte_probe, >> + .remove = spi_byte_remove, >> + .driver = { >> + .name = KBUILD_MODNAME, >> + .of_match_table = spi_byte_dt_ids, >> + }, >> +}; >> + >> +module_spi_driver(spi_byte_driver); >> + >> +MODULE_AUTHOR("Christian Mauderer <oss@c-mauderer.de>"); >> +MODULE_DESCRIPTION("single byte SPI LED driver"); >> +MODULE_LICENSE("GPL v2"); >> +MODULE_ALIAS("spi:leds-spi-byte"); >> > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver 2019-05-05 14:48 ` Jacek Anaszewski 2019-05-05 14:55 ` Christian Mauderer @ 2019-05-05 20:12 ` Pavel Machek 2019-05-06 8:48 ` Christian Mauderer 2019-05-06 18:19 ` Jacek Anaszewski 1 sibling, 2 replies; 8+ messages in thread From: Pavel Machek @ 2019-05-05 20:12 UTC (permalink / raw) To: Jacek Anaszewski Cc: oss, linux-leds, devicetree, Dan Murphy, Rob Herring, Mark Rutland [-- Attachment #1: Type: text/plain, Size: 672 bytes --] Hi! > >+ led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); > >+ if (!led) > >+ return -ENOMEM; > >+ > >+ led->spi = spi; > >+ strlcpy(led->name, name, sizeof(led->name)); > >+ mutex_init(&led->mutex); > >+ led->off_value = off_value; > >+ led->max_value = max_value; > >+ led->ldev.name = led->name; > >+ led->ldev.brightness = LED_OFF; > > This line is redundant - already zeroed by kzalloc. Actually I'd prefer to leave it in. Yes, LED_OFF == 0, and will probably stay == 0 in future, but... 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] 8+ messages in thread
* Re: [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver 2019-05-05 20:12 ` Pavel Machek @ 2019-05-06 8:48 ` Christian Mauderer 2019-05-06 18:34 ` Jacek Anaszewski 2019-05-06 18:19 ` Jacek Anaszewski 1 sibling, 1 reply; 8+ messages in thread From: Christian Mauderer @ 2019-05-06 8:48 UTC (permalink / raw) To: Pavel Machek, Jacek Anaszewski Cc: linux-leds, devicetree, Dan Murphy, Rob Herring, Mark Rutland On 05/05/2019 22:12, Pavel Machek wrote: > Hi! > >>> + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); >>> + if (!led) >>> + return -ENOMEM; >>> + >>> + led->spi = spi; >>> + strlcpy(led->name, name, sizeof(led->name)); >>> + mutex_init(&led->mutex); >>> + led->off_value = off_value; >>> + led->max_value = max_value; >>> + led->ldev.name = led->name; >>> + led->ldev.brightness = LED_OFF; >> >> This line is redundant - already zeroed by kzalloc. > > Actually I'd prefer to leave it in. Yes, LED_OFF == 0, and will > probably stay == 0 in future, but... > Pavel > Before I send v4: Currently the initial value isn't written to the LED anywhere. The state that is set by U-Boot is just kept till the first write to the brightness file. I didn't implement "default-state" because the OpenWRT user space sets the LED anyway a few seconds later (which is still my use case for that driver). But now I noted that there is a remark in the documentation of the option "default-state" in devicetree/bindings/leds/common.txt: "The default is off if this property is not present." Should I send an initial value to the device during initialization or is it OK to just keep the original state? Best regards Christian ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver 2019-05-06 8:48 ` Christian Mauderer @ 2019-05-06 18:34 ` Jacek Anaszewski 0 siblings, 0 replies; 8+ messages in thread From: Jacek Anaszewski @ 2019-05-06 18:34 UTC (permalink / raw) To: Christian Mauderer, Pavel Machek Cc: linux-leds, devicetree, Dan Murphy, Rob Herring, Mark Rutland Hi Christian, On 5/6/19 10:48 AM, Christian Mauderer wrote: > On 05/05/2019 22:12, Pavel Machek wrote: >> Hi! >> >>>> + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); >>>> + if (!led) >>>> + return -ENOMEM; >>>> + >>>> + led->spi = spi; >>>> + strlcpy(led->name, name, sizeof(led->name)); >>>> + mutex_init(&led->mutex); >>>> + led->off_value = off_value; >>>> + led->max_value = max_value; >>>> + led->ldev.name = led->name; >>>> + led->ldev.brightness = LED_OFF; >>> >>> This line is redundant - already zeroed by kzalloc. >> >> Actually I'd prefer to leave it in. Yes, LED_OFF == 0, and will >> probably stay == 0 in future, but... >> Pavel >> > > Before I send v4: Currently the initial value isn't written to the LED > anywhere. The state that is set by U-Boot is just kept till the first > write to the brightness file. > > I didn't implement "default-state" because the OpenWRT user space sets > the LED anyway a few seconds later (which is still my use case for that > driver). But now I noted that there is a remark in the documentation of > the option "default-state" in devicetree/bindings/leds/common.txt: "The > default is off if this property is not present." > > Should I send an initial value to the device during initialization or is > it OK to just keep the original state? Yes, I would make use of default-state in this case. -- Best regards, Jacek Anaszewski ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver 2019-05-05 20:12 ` Pavel Machek 2019-05-06 8:48 ` Christian Mauderer @ 2019-05-06 18:19 ` Jacek Anaszewski 1 sibling, 0 replies; 8+ messages in thread From: Jacek Anaszewski @ 2019-05-06 18:19 UTC (permalink / raw) To: Pavel Machek Cc: oss, linux-leds, devicetree, Dan Murphy, Rob Herring, Mark Rutland On 5/5/19 10:12 PM, Pavel Machek wrote: > Hi! > >>> + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); >>> + if (!led) >>> + return -ENOMEM; >>> + >>> + led->spi = spi; >>> + strlcpy(led->name, name, sizeof(led->name)); >>> + mutex_init(&led->mutex); >>> + led->off_value = off_value; >>> + led->max_value = max_value; >>> + led->ldev.name = led->name; >>> + led->ldev.brightness = LED_OFF; >> >> This line is redundant - already zeroed by kzalloc. > > Actually I'd prefer to leave it in. Yes, LED_OFF == 0, and will > probably stay == 0 in future, but... but what? I don't really see a sufficient justification for leaving it. Just redundant line. In other place in my LED naming patch set you wondered if it wouldn't have been better to initialize a struct partly using initialization list, I suspect to save few LOC. So here you seem to be inconsistent :-) -- Best regards, Jacek Anaszewski ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2019-05-06 18:34 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-05-05 12:52 [PATCH v2 1/2] dt-bindings: leds: Add binding for spi-byte LED oss 2019-05-05 12:52 ` [PATCH v2 2/2] leds: spi-byte: add single byte SPI LED driver oss 2019-05-05 14:48 ` Jacek Anaszewski 2019-05-05 14:55 ` Christian Mauderer 2019-05-05 20:12 ` Pavel Machek 2019-05-06 8:48 ` Christian Mauderer 2019-05-06 18:34 ` Jacek Anaszewski 2019-05-06 18:19 ` Jacek Anaszewski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).