/*
 * PCA9552 I2C LED blinker
 *
 *     https://www.nxp.com/docs/en/application-note/AN264.pdf
 *
 * Copyright (c) 2017-2018, IBM Corporation.
 * Copyright (c) 2020 Philippe Mathieu-Daudé
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * later. See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/bitops.h"
#include "hw/qdev-properties.h"
#include "hw/misc/pca9552.h"
#include "hw/misc/pca9552_regs.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "trace.h"
#include "qom/object.h"

struct PCA955xClass {
    /*< private >*/
    I2CSlaveClass parent_class;
    /*< public >*/

    uint8_t pin_count;
    uint8_t max_reg;
};
typedef struct PCA955xClass PCA955xClass;

DECLARE_CLASS_CHECKERS(PCA955xClass, PCA955X,
                       TYPE_PCA955X)

#define PCA9552_LED_ON   0x0
#define PCA9552_LED_OFF  0x1
#define PCA9552_LED_PWM0 0x2
#define PCA9552_LED_PWM1 0x3

static const char *led_state[] = {"on", "off", "pwm0", "pwm1"};

static uint8_t pca955x_pin_get_config(PCA955xState *s, int pin)
{
    uint8_t reg   = PCA9552_LS0 + (pin / 4);
    uint8_t shift = (pin % 4) << 1;

    return extract32(s->regs[reg], shift, 2);
}

/* Return INPUT status (bit #N belongs to GPIO #N) */
static uint16_t pca955x_pins_get_status(PCA955xState *s)
{
    return (s->regs[PCA9552_INPUT1] << 8) | s->regs[PCA9552_INPUT0];
}

static void pca955x_display_pins_status(PCA955xState *s,
                                        uint16_t previous_pins_status)
{
    PCA955xClass *k = PCA955X_GET_CLASS(s);
    uint16_t pins_status, pins_changed;
    int i;

    pins_status = pca955x_pins_get_status(s);
    pins_changed = previous_pins_status ^ pins_status;
    if (!pins_changed) {
        return;
    }
    if (trace_event_get_state_backends(TRACE_PCA955X_GPIO_STATUS)) {
        char *buf = g_newa(char, k->pin_count + 1);

        for (i = 0; i < k->pin_count; i++) {
            if (extract32(pins_status, i, 1)) {
                buf[i] = '*';
            } else {
                buf[i] = '.';
            }
        }
        buf[i] = '\0';
        trace_pca955x_gpio_status(s->description, buf);
    }
    if (trace_event_get_state_backends(TRACE_PCA955X_GPIO_CHANGE)) {
        for (i = 0; i < k->pin_count; i++) {
            if (extract32(pins_changed, i, 1)) {
                unsigned new_state = extract32(pins_status, i, 1);

                /*
                 * We display the state using the PCA logic ("active-high").
                 * This is not the state of the LED, which signal might be
                 * wired "active-low" on the board.
                 */
                trace_pca955x_gpio_change(s->description, i,
                                          !new_state, new_state);
            }
        }
    }
}

static void pca955x_update_pin_input(PCA955xState *s)
{
    PCA955xClass *k = PCA955X_GET_CLASS(s);
    int i;

    for (i = 0; i < k->pin_count; i++) {
        uint8_t input_reg = PCA9552_INPUT0 + (i / 8);
        uint8_t input_shift = (i % 8);
        uint8_t config = pca955x_pin_get_config(s, i);

        switch (config) {
        case PCA9552_LED_ON:
            qemu_set_irq(s->gpio[i], 1);
            s->regs[input_reg] |= 1 << input_shift;
            break;
        case PCA9552_LED_OFF:
            qemu_set_irq(s->gpio[i], 0);
            s->regs[input_reg] &= ~(1 << input_shift);
            break;
        case PCA9552_LED_PWM0:
        case PCA9552_LED_PWM1:
            /* TODO */
        default:
            break;
        }
    }
}

static uint8_t pca955x_read(PCA955xState *s, uint8_t reg)
{
    switch (reg) {
    case PCA9552_INPUT0:
    case PCA9552_INPUT1:
    case PCA9552_PSC0:
    case PCA9552_PWM0:
    case PCA9552_PSC1:
    case PCA9552_PWM1:
    case PCA9552_LS0:
    case PCA9552_LS1:
    case PCA9552_LS2:
    case PCA9552_LS3:
        return s->regs[reg];
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected read to register %d\n",
                      __func__, reg);
        return 0xFF;
    }
}

static void pca955x_write(PCA955xState *s, uint8_t reg, uint8_t data)
{
    uint16_t pins_status;

    switch (reg) {
    case PCA9552_PSC0:
    case PCA9552_PWM0:
    case PCA9552_PSC1:
    case PCA9552_PWM1:
        s->regs[reg] = data;
        break;

    case PCA9552_LS0:
    case PCA9552_LS1:
    case PCA9552_LS2:
    case PCA9552_LS3:
        pins_status = pca955x_pins_get_status(s);
        s->regs[reg] = data;
        pca955x_update_pin_input(s);
        pca955x_display_pins_status(s, pins_status);
        break;

    case PCA9552_INPUT0:
    case PCA9552_INPUT1:
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected write to register %d\n",
                      __func__, reg);
    }
}

/*
 * When Auto-Increment is on, the register address is incremented
 * after each byte is sent to or received by the device. The index
 * rollovers to 0 when the maximum register address is reached.
 */
static void pca955x_autoinc(PCA955xState *s)
{
    PCA955xClass *k = PCA955X_GET_CLASS(s);

    if (s->pointer != 0xFF && s->pointer & PCA9552_AUTOINC) {
        uint8_t reg = s->pointer & 0xf;

        reg = (reg + 1) % (k->max_reg + 1);
        s->pointer = reg | PCA9552_AUTOINC;
    }
}

static uint8_t pca955x_recv(I2CSlave *i2c)
{
    PCA955xState *s = PCA955X(i2c);
    uint8_t ret;

    ret = pca955x_read(s, s->pointer & 0xf);

    /*
     * From the Specs:
     *
     *     Important Note: When a Read sequence is initiated and the
     *     AI bit is set to Logic Level 1, the Read Sequence MUST
     *     start by a register different from 0.
     *
     * I don't know what should be done in this case, so throw an
     * error.
     */
    if (s->pointer == PCA9552_AUTOINC) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Autoincrement read starting with register 0\n",
                      __func__);
    }

    pca955x_autoinc(s);

    return ret;
}

static int pca955x_send(I2CSlave *i2c, uint8_t data)
{
    PCA955xState *s = PCA955X(i2c);

    /* First byte sent by is the register address */
    if (s->len == 0) {
        s->pointer = data;
        s->len++;
    } else {
        pca955x_write(s, s->pointer & 0xf, data);

        pca955x_autoinc(s);
    }

    return 0;
}

static int pca955x_event(I2CSlave *i2c, enum i2c_event event)
{
    PCA955xState *s = PCA955X(i2c);

    s->len = 0;
    return 0;
}

static void pca955x_get_led(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
{
    PCA955xClass *k = PCA955X_GET_CLASS(obj);
    PCA955xState *s = PCA955X(obj);
    int led, rc, reg;
    uint8_t state;

    rc = sscanf(name, "led%2d", &led);
    if (rc != 1) {
        error_setg(errp, "%s: error reading %s", __func__, name);
        return;
    }
    if (led < 0 || led > k->pin_count) {
        error_setg(errp, "%s invalid led %s", __func__, name);
        return;
    }
    /*
     * Get the LSx register as the qom interface should expose the device
     * state, not the modeled 'input line' behaviour which would come from
     * reading the INPUTx reg
     */
    reg = PCA9552_LS0 + led / 4;
    state = (pca955x_read(s, reg) >> ((led % 4) * 2)) & 0x3;
    visit_type_str(v, name, (char **)&led_state[state], errp);
}

/*
 * Return an LED selector register value based on an existing one, with
 * the appropriate 2-bit state value set for the given LED number (0-3).
 */
static inline uint8_t pca955x_ledsel(uint8_t oldval, int led_num, int state)
{
        return (oldval & (~(0x3 << (led_num << 1)))) |
                ((state & 0x3) << (led_num << 1));
}

static void pca955x_set_led(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
{
    PCA955xClass *k = PCA955X_GET_CLASS(obj);
    PCA955xState *s = PCA955X(obj);
    int led, rc, reg, val;
    uint8_t state;
    char *state_str;

    if (!visit_type_str(v, name, &state_str, errp)) {
        return;
    }
    rc = sscanf(name, "led%2d", &led);
    if (rc != 1) {
        error_setg(errp, "%s: error reading %s", __func__, name);
        return;
    }
    if (led < 0 || led > k->pin_count) {
        error_setg(errp, "%s invalid led %s", __func__, name);
        return;
    }

    for (state = 0; state < ARRAY_SIZE(led_state); state++) {
        if (!strcmp(state_str, led_state[state])) {
            break;
        }
    }
    if (state >= ARRAY_SIZE(led_state)) {
        error_setg(errp, "%s invalid led state %s", __func__, state_str);
        return;
    }

    reg = PCA9552_LS0 + led / 4;
    val = pca955x_read(s, reg);
    val = pca955x_ledsel(val, led % 4, state);
    pca955x_write(s, reg, val);
}

static const VMStateDescription pca9552_vmstate = {
    .name = "PCA9552",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(len, PCA955xState),
        VMSTATE_UINT8(pointer, PCA955xState),
        VMSTATE_UINT8_ARRAY(regs, PCA955xState, PCA955X_NR_REGS),
        VMSTATE_I2C_SLAVE(i2c, PCA955xState),
        VMSTATE_END_OF_LIST()
    }
};

static void pca9552_reset(DeviceState *dev)
{
    PCA955xState *s = PCA955X(dev);

    s->regs[PCA9552_PSC0] = 0xFF;
    s->regs[PCA9552_PWM0] = 0x80;
    s->regs[PCA9552_PSC1] = 0xFF;
    s->regs[PCA9552_PWM1] = 0x80;
    s->regs[PCA9552_LS0] = 0x55; /* all OFF */
    s->regs[PCA9552_LS1] = 0x55;
    s->regs[PCA9552_LS2] = 0x55;
    s->regs[PCA9552_LS3] = 0x55;

    pca955x_update_pin_input(s);

    s->pointer = 0xFF;
    s->len = 0;
}

static void pca955x_initfn(Object *obj)
{
    PCA955xClass *k = PCA955X_GET_CLASS(obj);
    int led;

    assert(k->pin_count <= PCA955X_PIN_COUNT_MAX);
    for (led = 0; led < k->pin_count; led++) {
        char *name;

        name = g_strdup_printf("led%d", led);
        object_property_add(obj, name, "bool", pca955x_get_led, pca955x_set_led,
                            NULL, NULL);
        g_free(name);
    }
}

static void pca955x_realize(DeviceState *dev, Error **errp)
{
    PCA955xClass *k = PCA955X_GET_CLASS(dev);
    PCA955xState *s = PCA955X(dev);

    if (!s->description) {
        s->description = g_strdup("pca-unspecified");
    }

    qdev_init_gpio_out(dev, s->gpio, k->pin_count);
}

static Property pca955x_properties[] = {
    DEFINE_PROP_STRING("description", PCA955xState, description),
    DEFINE_PROP_END_OF_LIST(),
};

static void pca955x_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);

    k->event = pca955x_event;
    k->recv = pca955x_recv;
    k->send = pca955x_send;
    dc->realize = pca955x_realize;
    device_class_set_props(dc, pca955x_properties);
}

static const TypeInfo pca955x_info = {
    .name          = TYPE_PCA955X,
    .parent        = TYPE_I2C_SLAVE,
    .instance_init = pca955x_initfn,
    .instance_size = sizeof(PCA955xState),
    .class_init    = pca955x_class_init,
    .class_size    = sizeof(PCA955xClass),
    .abstract      = true,
};

static void pca9552_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    PCA955xClass *pc = PCA955X_CLASS(oc);

    dc->reset = pca9552_reset;
    dc->vmsd = &pca9552_vmstate;
    pc->max_reg = PCA9552_LS3;
    pc->pin_count = 16;
}

static const TypeInfo pca9552_info = {
    .name          = TYPE_PCA9552,
    .parent        = TYPE_PCA955X,
    .class_init    = pca9552_class_init,
};

static void pca955x_register_types(void)
{
    type_register_static(&pca955x_info);
    type_register_static(&pca9552_info);
}

type_init(pca955x_register_types)
