1# LED Support for OpenBMC
2
3This document describes how to add LED support for your machine based upon the
4OpenBMC [LED Architecture][led d-bus readme] document. LED group management is
5done automatically for machines that support the use of the MRW and is beyond
6the scope of this document.
7
8## D-Bus
9
10```
11Service     xyx.openbmc_project.LED.GroupManager
12Path        /xyz/openbmc_project/led/groups/<label>
13Interfaces  xyz.openbmc_project.Led.Group
14
15Signals: none
16Attribute: Asserted (boolean)
17```
18
19## REST
20
21```
22PUT /xyz/openbmc_project/led/groups/<group>/attr/Asserted
23```
24
25The LED group state can be changed by setting the Asserted value to boolean 0
26or 1. In the following example, the lamp_test group is being asserted...
27
28```
29 curl -b cjar -k -X PUT -H "Content-Type: application/json" -d '{"data":  1}' \
30  https://${bmc}/xyz/openbmc_project/led/groups/lamp_test/attr/Asserted
31```
32
33## REDFISH
34
35### Resource identify Operation
36
37Starting with Redfish v2020.3, Redfish resources have
38**LocationIndicatorActive** property, which is used to identify a particular
39resource. This is for LED Identify operation only.
40
41All applicable Inventory D-Bus objects would have a forward association mapping
42to LED Group D-Bus object, namely:
43
44```
45 - identify_led_group
46```
47
48All applicable LED Group D-Bus objects would have an association mapping to
49inventory D-Bus object, namely:
50
51```
52 - identify_inventory_object
53```
54
55When a `LocationIndicatorActive` GET operation is performed on the resource,
56bmcweb does below operations:
57
58- Look for an association `identify_led_group` on the Inventory D-Bus object
59- If found, read the `asserted` property from the D-Bus object that is pointed
60  to by `identify_led_group`
61
62When a `LocationIndicatorActive` PATCH operation is performed on the resource,
63bmcweb does below operations:
64
65- Look for an association `identify_led_group` on the Inventory D-Bus object
66- If found, set the `asserted` property on the D-Bus object that is pointed to
67  by `identify_led_group`
68
69### Representing resource faults
70
71For representing the fault status of a resource, Redfish `Health` property is
72used. All applicable Inventory D-Bus objects would have a forward association
73mapping to LED Group D-Bus object, namely;
74
75```
76 - fault_led_group
77```
78
79All applicable LED Group D-Bus objects would have an association mapping to
80inventory D-Bus object, namely:
81
82```
83 - fault_inventory_object
84```
85
86When a component fault is detected, the responsible code sets the `Functional`
87property of `xyz.openbmc_project.State.Decorator.OperationalStatus` to `false`
88on the Inventory D-Bus object.
89
90When LED manager gets PropertyChanged signal, it does the following:
91
92- Look for an association `fault_led_group` on the Inventory D-Bus object
93- Turn on/off the fault LED group depending on the value of `Functional` `false`
94  would mean turn ON the LED group `true` would mean turn OFF the LED group
95
96- bmcweb already has a design to look for `Functional` property and set the
97  `Health` property.
98
99## Development Details
100
101There are two significant layers for LED operations. The physical and the
102logical. The LED Group Manager communicates with the physical LED Manager to
103drive the physical LEDs. The logical groups are defined in the machine's
104led.yaml file. LED Group manager consumes this and creates D-Bus/REST interfaces
105for the individual LEDs that are part of the group.
106
107### Defining the physical LED
108
109Physical LED wiring is defined in the `leds` section of the machine's [device
110tree][kernel arm dts]. See the [Palmetto DTS][palmetto dts led] as an example.
111
112_Add a fault LED to the device tree with a corresponding gpio pin..._
113
114```
115  leds {
116    compatible = "gpio-leds";
117
118    fault {
119      gpios = <&gpio ASPEED_GPIO(N, 2) GPIO_ACTIVE_LOW>;
120    };
121  }
122```
123
124_The kernel will then create..._
125
126```
127 ls -l /sys/class/leds/fault/
128total 0
129-rw-r--r--    1 root     root          4096 Jun 21 20:04 brightness
130lrwxrwxrwx    1 root     root             0 Jun 21 20:29 device -> ../../../leds
131-r--r--r--    1 root     root          4096 Jun 21 20:29 max_brightness
132drwxr-xr-x    2 root     root             0 Jun 21 20:29 power
133lrwxrwxrwx    1 root     root             0 Jun 21 20:04 subsystem -> ../../../../../class/leds
134-rw-r--r--    1 root     root          4096 Jun 21 20:04 trigger
135-rw-r--r--    1 root     root          4096 Jun 21 20:04 uevent
136```
137
138### Defining Groups
139
140An LED Group can contain zero or more LEDs and is defined in the machines
141[led.yaml][led yaml]. The default one will likely need to be tailored to your
142machines layout. Customized yaml files are placed into the machines specific
143Yocto location. As an example:
144
145```
146meta-ibm/meta-palmetto/recipes-phosphor/leds/palmetto-led-manager-config/led.yaml
147```
148
149The parent properties in the yaml file will be created below
150`/xyz/openbmc_project/led/groups/`. The children properties need to map to an
151LED name in `/sys/class/leds`.
152
153In the example, below two URIs would be created:
154`/xyz/openbmc_project/led/groups/enclosure_fault` and
155`/xyz/openbmc_project/led/groups/lamp_test`. Both act on the same physical LED
156`fault` but do so differently. The lamp_test would also drive a blink signal to
157the physical `power` LED if one was created.
158
159```
160EnclosureFault:
161    fault:
162        Action: 'On'
163        DutyOn: 50
164        Period: 0
165lamp_test:
166    fault:
167        Action: 'Blink'
168        DutyOn: 20
169        Period: 100
170    power:
171        Action: 'Blink'
172        DutyOn: 20
173        Period: 100
174
175```
176
177### Required Groups
178
179OpenBMC Architecture requires specific LED Groups to be created and are
180documented in the [D-Bus interface][led d-bus readme].
181
182## Yocto packaging
183
1841.  Create a tailored LED manager file
185
186    E.g.
187    `meta-ibm/meta-romulus/recipes-phosphor/leds/romulus-led-manager-config-native.bb`
188
189    ```
190    SUMMARY = "Phosphor LED Group Management for Romulus"
191    PR = "r1"
192
193    inherit native
194    inherit obmc-phosphor-utils
195    inherit obmc-phosphor-license
196
197    PROVIDES += "virtual/phosphor-led-manager-config-native"
198
199    SRC_URI += "file://led.yaml"
200    S = "${WORKDIR}"
201
202    # Overwrites the default led.yaml
203    do_install() {
204        SRC=${S}
205        DEST=${D}${datadir}/phosphor-led-manager
206        install -D ${SRC}/led.yaml ${DEST}/led.yaml
207    }
208    ```
209
2102.  Change your machine's preferred provider for the led-manager in the conf
211    file
212
213    E.g. `meta-ibm/meta-romulus/conf/machine/romulus.conf`
214
215    `PREFERRED_PROVIDER_virtual/phosphor-led-manager-config-native = "romulus-led-manager-config-native"`
216
217[led d-bus readme]:
218  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Led/README.md
219[led yaml]: https://github.com/openbmc/phosphor-led-manager/blob/master/led.yaml
220[kernel arm dts]:
221  https://github.com/openbmc/linux/tree/dev-4.19/arch/arm/boot/dts
222[palmetto dts led]:
223  https://github.com/openbmc/linux/blob/dev-4.19/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts#L45
224