Re: [PATCH 2/3] dt-bindings: leds: add dt schema for worldsemi,ws2812b-spi

From: Chuanhong Guo
Date: Wed Nov 30 2022 - 03:37:12 EST


Hi!

On Wed, Nov 30, 2022 at 12:54 AM Krzysztof Kozlowski
<krzysztof.kozlowski@xxxxxxxxxx> wrote:
> > +description: |
> > + WorldSemi WS2812B is a individually addressable LED chip that can be chained
> > + together and controlled individually using a single wire.
> > + This driver simulates the protocol used by this LED chip with SPI bus.
>
> Drop references to Linux driver, unless important for the binding.

I think the SPI part is important. (I'll explain it below.) What about:

This binding describes a chain of WS2812B LEDs connected to the SPI MOSI pin.

instead?

> > + Typical setups includes connecting the data pin of the LED chain to MOSI as
> > + the only device or using CS and MOSI with a tri-state voltage-level shifter
> > + for the data pin.
> > + The SPI frequency needs to be 2.105MHz~2.85MHz for the timing to be correct
> > + and the controller needs to send all the bytes continuously.
> > +
> > +allOf:
> > + - $ref: /schemas/spi/spi-peripheral-props.yaml#
> > +
> > +properties:
> > + compatible:
> > + const: worldsemi,ws2812b-spi
>
> Drop "-spi". Compatibles are not supposed to include bus information.
> The same for file name.

WS2812B isn't a SPI chip. It's controlled with only a single wire and
can be driven
using anything that can produce a long and a short pulse meeting its timing
requirement.
This driver uses a SPI bus to send the pulses, but it can also be
controlled with
I2S and the PIO pins on a Raspberry Pi Pico.
This spi suffix is to distinguish it from other possible
implementations if someone
else submits a support with a different peripheral.

>
> > +
> > + reg:
> > + description: The chip-select line on the SPI bus
>
> Drop description, it's obvious.

OK.

>
> > + maxItems: 1
> > +
> > + spi-max-frequency:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + Maximum SPI clocking speed of the device in Hz.
>
> No need for ref and description. It comes from spi-peripheral-props.

OK.

>
> > + minimum: 2105000
> > + maximum: 2850000
> > +
> > + "#address-cells":
> > + const: 1
> > +
> > + "#size-cells":
> > + const: 0
> > +
> > +patternProperties:
> > + "^multi-led(@[0-9a-f])?$":
>
> Why unit address is optional?

It isn't. I copy-pasted it from led-class-multicolor.yaml and
didn't check the exact regex.
I'll fix it in the next version.

>
> > + type: object
> > + $ref: leds-class-multicolor.yaml#
>
> unevaluatedProperties: false

OK.

> > +
> > + properties:
> > + color-index:
> > + description: |
> > + A 3-item array specifying color of each components in this LED. It
> > + should be one of the LED_COLOR_ID_* prefixed definitions from the
> > + header include/dt-bindings/leds/common.h. Defaults to
> > + <LED_COLOR_ID_GREEN LED_COLOR_ID_RED LED_COLOR_ID_BLUE>
> > + if unspecified.
> > + $ref: /schemas/types.yaml#/definitions/uint32-array
> > + minItems: 3
>
> Drop minItems.... but see comment below:
>
> > + maxItems: 3
>
> Why this is different than other multi-color LEDs? I would expect here
> children with common.yaml.

WS2812B is a single LED package with 3 diodes and a microcontroller.
Each LED package has 3 colors. The original chip comes with GRB
color while there are some clones with RGB arrangement instead.
The LED chain can be really long so I'd like to simplify the binding
by using a single property to override the only variable, color, here.

>
> > +
> > + default-intensity:
> > + description: |
> > + An array of 3 integer specifying the default intensity of each color
> > + components in this LED. <255 255 255> if unspecified.
> > + $ref: /schemas/types.yaml#/definitions/uint32-array
> > + minItems: 3
>
> Drop minItems.... but:
>
> > + maxItems: 3
> > + items:
> > + minimum: 0
> > + maximum: 255
>
> default: 255
>
> What controls the intensity? Don't you have PWM there?

The LED takes 3-byte brightness value of each color. This property is used to
specify the default multi_intensity field for the multi-color LED. The final
brightness value is calculated with led_mc_calc_color_components like this:

mcled_cdev->subled_info[i].brightness = brightness *
mcled_cdev->subled_info[i].intensity / led_cdev->max_brightness;

The LED chip takes exactly 8 bits for the brightness (max_brightness = 255
which can't be changed.), so according to the formula above the maximum
intensity should be 255.

>
> > +
> > + reg:
> > + description: |
> > + Which LED this node represents. The reg of the first LED on the chain
> > + is 0.
>
> maxItems: 1

OK.

>
> > +
> > + required:
> > + - reg
> > + - color
> > + - function
> > +
> > +required:
> > + - compatible
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + #include <dt-bindings/leds/common.h>
> > + spi {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + ws2812b@0 {
>
> Node names should be generic.
> https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation

OK. I'll use leds instead.

>
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + compatible = "worldsemi,ws2812b-spi";
> > + reg = <0>;
>
> compatible is first property, reg is second.

Got it.

--
Regards,
Chuanhong Guo