/*
 * QEMU single LED device
 *
 * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "hw/misc/led.h"
#include "hw/irq.h"
#include "trace.h"

#define LED_INTENSITY_PERCENT_MAX   100

static const char * const led_color_name[] = {
    [LED_COLOR_VIOLET]  = "violet",
    [LED_COLOR_BLUE]    = "blue",
    [LED_COLOR_CYAN]    = "cyan",
    [LED_COLOR_GREEN]   = "green",
    [LED_COLOR_YELLOW]  = "yellow",
    [LED_COLOR_AMBER]   = "amber",
    [LED_COLOR_ORANGE]  = "orange",
    [LED_COLOR_RED]     = "red",
};

static bool led_color_name_is_valid(const char *color_name)
{
    for (size_t i = 0; i < ARRAY_SIZE(led_color_name); i++) {
        if (strcmp(color_name, led_color_name[i]) == 0) {
            return true;
        }
    }
    return false;
}

void led_set_intensity(LEDState *s, unsigned intensity_percent)
{
    if (intensity_percent > LED_INTENSITY_PERCENT_MAX) {
        intensity_percent = LED_INTENSITY_PERCENT_MAX;
    }
    trace_led_set_intensity(s->description, s->color, intensity_percent);
    if (intensity_percent != s->intensity_percent) {
        trace_led_change_intensity(s->description, s->color,
                                   s->intensity_percent, intensity_percent);
    }
    s->intensity_percent = intensity_percent;
}

unsigned led_get_intensity(LEDState *s)
{
    return s->intensity_percent;
}

void led_set_state(LEDState *s, bool is_emitting)
{
    led_set_intensity(s, is_emitting ? LED_INTENSITY_PERCENT_MAX : 0);
}

static void led_set_state_gpio_handler(void *opaque, int line, int new_state)
{
    LEDState *s = LED(opaque);

    assert(line == 0);
    led_set_state(s, !!new_state != s->gpio_active_high);
}

static void led_reset(DeviceState *dev)
{
    LEDState *s = LED(dev);

    led_set_state(s, s->gpio_active_high);
}

static const VMStateDescription vmstate_led = {
    .name = TYPE_LED,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(intensity_percent, LEDState),
        VMSTATE_END_OF_LIST()
    }
};

static void led_realize(DeviceState *dev, Error **errp)
{
    LEDState *s = LED(dev);

    if (s->color == NULL) {
        error_setg(errp, "property 'color' not specified");
        return;
    } else if (!led_color_name_is_valid(s->color)) {
        error_setg(errp, "property 'color' invalid or not supported");
        return;
    }
    if (s->description == NULL) {
        s->description = g_strdup("n/a");
    }

    qdev_init_gpio_in(DEVICE(s), led_set_state_gpio_handler, 1);
}

static Property led_properties[] = {
    DEFINE_PROP_STRING("color", LEDState, color),
    DEFINE_PROP_STRING("description", LEDState, description),
    DEFINE_PROP_BOOL("gpio-active-high", LEDState, gpio_active_high, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void led_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->desc = "LED";
    dc->vmsd = &vmstate_led;
    dc->reset = led_reset;
    dc->realize = led_realize;
    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
    device_class_set_props(dc, led_properties);
}

static const TypeInfo led_info = {
    .name = TYPE_LED,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(LEDState),
    .class_init = led_class_init
};

static void led_register_types(void)
{
    type_register_static(&led_info);
}

type_init(led_register_types)

LEDState *led_create_simple(Object *parentobj,
                            GpioPolarity gpio_polarity,
                            LEDColor color,
                            const char *description)
{
    g_autofree char *name = NULL;
    DeviceState *dev;

    dev = qdev_new(TYPE_LED);
    qdev_prop_set_bit(dev, "gpio-active-high",
                      gpio_polarity == GPIO_POLARITY_ACTIVE_HIGH);
    qdev_prop_set_string(dev, "color", led_color_name[color]);
    if (!description) {
        static unsigned undescribed_led_id;
        name = g_strdup_printf("undescribed-led-#%u", undescribed_led_id++);
    } else {
        qdev_prop_set_string(dev, "description", description);
        name = g_ascii_strdown(description, -1);
        name = g_strdelimit(name, " #", '-');
    }
    object_property_add_child(parentobj, name, OBJECT(dev));
    qdev_realize_and_unref(dev, NULL, &error_fatal);

    return LED(dev);
}
