Lines Matching +full:led +full:-
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * leds-ns2.c - Driver for the Network Space v2 (and parents) dual-GPIO LED
9 * Based on leds-gpio.c by Raphael Assenat <raph@8d.com>
39 * The Network Space v2 dual-GPIO LED is wired to a CPLD. Three different LED
40 * modes are available: off, on and SATA activity blinking. The LED modes are
42 * for the command/slow GPIOs corresponds to a LED mode.
56 static int ns2_led_get_mode(struct ns2_led *led, enum ns2_led_modes *mode) in ns2_led_get_mode() argument
62 cmd_level = gpiod_get_value_cansleep(led->cmd); in ns2_led_get_mode()
63 slow_level = gpiod_get_value_cansleep(led->slow); in ns2_led_get_mode()
65 for (i = 0; i < led->num_modes; i++) { in ns2_led_get_mode()
66 if (cmd_level == led->modval[i].cmd_level && in ns2_led_get_mode()
67 slow_level == led->modval[i].slow_level) { in ns2_led_get_mode()
68 *mode = led->modval[i].mode; in ns2_led_get_mode()
73 return -EINVAL; in ns2_led_get_mode()
76 static void ns2_led_set_mode(struct ns2_led *led, enum ns2_led_modes mode) in ns2_led_set_mode() argument
81 for (i = 0; i < led->num_modes; i++) in ns2_led_set_mode()
82 if (mode == led->modval[i].mode) in ns2_led_set_mode()
85 if (i == led->num_modes) in ns2_led_set_mode()
88 write_lock_irqsave(&led->rw_lock, flags); in ns2_led_set_mode()
90 if (!led->can_sleep) { in ns2_led_set_mode()
91 gpiod_set_value(led->cmd, led->modval[i].cmd_level); in ns2_led_set_mode()
92 gpiod_set_value(led->slow, led->modval[i].slow_level); in ns2_led_set_mode()
96 gpiod_set_value_cansleep(led->cmd, led->modval[i].cmd_level); in ns2_led_set_mode()
97 gpiod_set_value_cansleep(led->slow, led->modval[i].slow_level); in ns2_led_set_mode()
100 write_unlock_irqrestore(&led->rw_lock, flags); in ns2_led_set_mode()
106 struct ns2_led *led = container_of(led_cdev, struct ns2_led, cdev); in ns2_led_set() local
111 else if (led->sata) in ns2_led_set()
116 ns2_led_set_mode(led, mode); in ns2_led_set()
131 struct ns2_led *led = container_of(led_cdev, struct ns2_led, cdev); in ns2_led_sata_store() local
141 if (led->sata == enable) in ns2_led_sata_store()
144 led->sata = enable; in ns2_led_sata_store()
150 ns2_led_set_mode(led, NS_V2_LED_SATA); in ns2_led_sata_store()
152 ns2_led_set_mode(led, NS_V2_LED_ON); in ns2_led_sata_store()
162 struct ns2_led *led = container_of(led_cdev, struct ns2_led, cdev); in ns2_led_sata_show() local
164 return sprintf(buf, "%d\n", led->sata); in ns2_led_sata_show()
176 struct ns2_led *led) in ns2_led_register() argument
183 led->cmd = devm_fwnode_gpiod_get_index(dev, node, "cmd", 0, GPIOD_ASIS, in ns2_led_register()
185 if (IS_ERR(led->cmd)) in ns2_led_register()
186 return PTR_ERR(led->cmd); in ns2_led_register()
188 led->slow = devm_fwnode_gpiod_get_index(dev, node, "slow", 0, in ns2_led_register()
191 if (IS_ERR(led->slow)) in ns2_led_register()
192 return PTR_ERR(led->slow); in ns2_led_register()
194 ret = fwnode_property_count_u32(node, "modes-map"); in ns2_led_register()
196 dev_err(dev, "Missing or malformed modes-map for %pfw\n", node); in ns2_led_register()
197 return -EINVAL; in ns2_led_register()
203 return -ENOMEM; in ns2_led_register()
205 fwnode_property_read_u32_array(node, "modes-map", (void *)modval, in ns2_led_register()
208 rwlock_init(&led->rw_lock); in ns2_led_register()
210 led->cdev.blink_set = NULL; in ns2_led_register()
211 led->cdev.flags |= LED_CORE_SUSPENDRESUME; in ns2_led_register()
212 led->cdev.groups = ns2_led_groups; in ns2_led_register()
213 led->can_sleep = gpiod_cansleep(led->cmd) || gpiod_cansleep(led->slow); in ns2_led_register()
214 if (led->can_sleep) in ns2_led_register()
215 led->cdev.brightness_set_blocking = ns2_led_set_blocking; in ns2_led_register()
217 led->cdev.brightness_set = ns2_led_set; in ns2_led_register()
218 led->num_modes = nmodes; in ns2_led_register()
219 led->modval = modval; in ns2_led_register()
221 ret = ns2_led_get_mode(led, &mode); in ns2_led_register()
225 /* Set LED initial state. */ in ns2_led_register()
226 led->sata = (mode == NS_V2_LED_SATA) ? 1 : 0; in ns2_led_register()
227 led->cdev.brightness = (mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL; in ns2_led_register()
231 ret = devm_led_classdev_register_ext(dev, &led->cdev, &init_data); in ns2_led_register()
233 dev_err(dev, "Failed to register LED for node %pfw\n", node); in ns2_led_register()
240 struct device *dev = &pdev->dev; in ns2_led_probe()
248 return -ENODEV; in ns2_led_probe()
252 return -ENOMEM; in ns2_led_probe()
266 { .compatible = "lacie,ns2-leds", },
274 .name = "leds-ns2",
282 MODULE_DESCRIPTION("Network Space v2 LED driver");
284 MODULE_ALIAS("platform:leds-ns2");