| /* |
| * Copyright (c) 2021 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #define DT_DRV_COMPAT gpio_leds |
| |
| /** |
| * @file |
| * @brief GPIO driven LEDs |
| */ |
| |
| #include <zephyr/drivers/led.h> |
| #include <zephyr/drivers/gpio.h> |
| #include <zephyr/device.h> |
| #include <zephyr/zephyr.h> |
| |
| #include <zephyr/logging/log.h> |
| LOG_MODULE_REGISTER(led_gpio, CONFIG_LED_LOG_LEVEL); |
| |
| struct led_gpio_config { |
| size_t num_leds; |
| const struct gpio_dt_spec *led; |
| }; |
| |
| static int led_gpio_set_brightness(const struct device *dev, uint32_t led, uint8_t value) |
| { |
| |
| const struct led_gpio_config *config = dev->config; |
| const struct gpio_dt_spec *led_gpio; |
| |
| if ((led >= config->num_leds) || (value > 100)) { |
| return -EINVAL; |
| } |
| |
| led_gpio = &config->led[led]; |
| |
| return gpio_pin_set_dt(led_gpio, value > 0); |
| } |
| |
| static int led_gpio_on(const struct device *dev, uint32_t led) |
| { |
| return led_gpio_set_brightness(dev, led, 100); |
| } |
| |
| static int led_gpio_off(const struct device *dev, uint32_t led) |
| { |
| return led_gpio_set_brightness(dev, led, 0); |
| } |
| |
| static int led_gpio_init(const struct device *dev) |
| { |
| const struct led_gpio_config *config = dev->config; |
| int err = 0; |
| |
| if (!config->num_leds) { |
| LOG_ERR("%s: no LEDs found (DT child nodes missing)", dev->name); |
| err = -ENODEV; |
| } |
| |
| for (size_t i = 0; (i < config->num_leds) && !err; i++) { |
| const struct gpio_dt_spec *led = &config->led[i]; |
| |
| if (device_is_ready(led->port)) { |
| err = gpio_pin_configure_dt(led, GPIO_OUTPUT_INACTIVE); |
| |
| if (err) { |
| LOG_ERR("Cannot configure GPIO (err %d)", err); |
| } |
| } else { |
| LOG_ERR("%s: GPIO device not ready", dev->name); |
| err = -ENODEV; |
| } |
| } |
| |
| return err; |
| } |
| |
| static const struct led_driver_api led_gpio_api = { |
| .on = led_gpio_on, |
| .off = led_gpio_off, |
| .set_brightness = led_gpio_set_brightness, |
| }; |
| |
| #define LED_GPIO_DT_SPEC(led_node_id) \ |
| GPIO_DT_SPEC_GET(led_node_id, gpios), \ |
| |
| #define LED_GPIO_DEVICE(i) \ |
| \ |
| static const struct gpio_dt_spec gpio_dt_spec_##i[] = { \ |
| DT_INST_FOREACH_CHILD(i, LED_GPIO_DT_SPEC) \ |
| }; \ |
| \ |
| static const struct led_gpio_config led_gpio_config_##i = { \ |
| .num_leds = ARRAY_SIZE(gpio_dt_spec_##i), \ |
| .led = gpio_dt_spec_##i, \ |
| }; \ |
| \ |
| DEVICE_DT_INST_DEFINE(i, &led_gpio_init, NULL, \ |
| NULL, &led_gpio_config_##i, \ |
| POST_KERNEL, CONFIG_LED_INIT_PRIORITY, \ |
| &led_gpio_api); |
| |
| DT_INST_FOREACH_STATUS_OKAY(LED_GPIO_DEVICE) |