/*
 * Analog Devices ADM1266 Cascadable Super Sequencer with Margin Control and
 * Fault Recording with PMBus
 *
 * https://www.analog.com/media/en/technical-documentation/data-sheets/adm1266.pdf
 *
 * Copyright 2023 Google LLC
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "hw/i2c/pmbus_device.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/log.h"
#include "qemu/module.h"

#define TYPE_ADM1266 "adm1266"
OBJECT_DECLARE_SIMPLE_TYPE(ADM1266State, ADM1266)

#define ADM1266_BLACKBOX_CONFIG                 0xD3
#define ADM1266_PDIO_CONFIG                     0xD4
#define ADM1266_READ_STATE                      0xD9
#define ADM1266_READ_BLACKBOX                   0xDE
#define ADM1266_SET_RTC                         0xDF
#define ADM1266_GPIO_SYNC_CONFIGURATION         0xE1
#define ADM1266_BLACKBOX_INFORMATION            0xE6
#define ADM1266_PDIO_STATUS                     0xE9
#define ADM1266_GPIO_STATUS                     0xEA

/* Defaults */
#define ADM1266_OPERATION_DEFAULT               0x80
#define ADM1266_CAPABILITY_DEFAULT              0xA0
#define ADM1266_CAPABILITY_NO_PEC               0x20
#define ADM1266_PMBUS_REVISION_DEFAULT          0x22
#define ADM1266_MFR_ID_DEFAULT                  "ADI"
#define ADM1266_MFR_ID_DEFAULT_LEN              32
#define ADM1266_MFR_MODEL_DEFAULT               "ADM1266-A1"
#define ADM1266_MFR_MODEL_DEFAULT_LEN           32
#define ADM1266_MFR_REVISION_DEFAULT            "25"
#define ADM1266_MFR_REVISION_DEFAULT_LEN        8

#define ADM1266_NUM_PAGES               17
/**
 * PAGE Index
 * Page 0 VH1.
 * Page 1 VH2.
 * Page 2 VH3.
 * Page 3 VH4.
 * Page 4 VP1.
 * Page 5 VP2.
 * Page 6 VP3.
 * Page 7 VP4.
 * Page 8 VP5.
 * Page 9 VP6.
 * Page 10 VP7.
 * Page 11 VP8.
 * Page 12 VP9.
 * Page 13 VP10.
 * Page 14 VP11.
 * Page 15 VP12.
 * Page 16 VP13.
 */
typedef struct ADM1266State {
    PMBusDevice parent;

    char mfr_id[32];
    char mfr_model[32];
    char mfr_rev[8];
} ADM1266State;

static const uint8_t adm1266_ic_device_id[] = {0x03, 0x41, 0x12, 0x66};
static const uint8_t adm1266_ic_device_rev[] = {0x08, 0x01, 0x08, 0x07, 0x0,
                                                0x0, 0x07, 0x41, 0x30};

static void adm1266_exit_reset(Object *obj, ResetType type)
{
    ADM1266State *s = ADM1266(obj);
    PMBusDevice *pmdev = PMBUS_DEVICE(obj);

    pmdev->page = 0;
    pmdev->capability = ADM1266_CAPABILITY_NO_PEC;

    for (int i = 0; i < ADM1266_NUM_PAGES; i++) {
        pmdev->pages[i].operation = ADM1266_OPERATION_DEFAULT;
        pmdev->pages[i].revision = ADM1266_PMBUS_REVISION_DEFAULT;
        pmdev->pages[i].vout_mode = 0;
        pmdev->pages[i].read_vout = pmbus_data2linear_mode(12, 0);
        pmdev->pages[i].vout_margin_high = pmbus_data2linear_mode(15, 0);
        pmdev->pages[i].vout_margin_low = pmbus_data2linear_mode(3, 0);
        pmdev->pages[i].vout_ov_fault_limit = pmbus_data2linear_mode(16, 0);
        pmdev->pages[i].revision = ADM1266_PMBUS_REVISION_DEFAULT;
    }

    strncpy(s->mfr_id, ADM1266_MFR_ID_DEFAULT, 4);
    strncpy(s->mfr_model, ADM1266_MFR_MODEL_DEFAULT, 11);
    strncpy(s->mfr_rev, ADM1266_MFR_REVISION_DEFAULT, 3);
}

static uint8_t adm1266_read_byte(PMBusDevice *pmdev)
{
    ADM1266State *s = ADM1266(pmdev);

    switch (pmdev->code) {
    case PMBUS_MFR_ID:                    /* R/W block */
        pmbus_send_string(pmdev, s->mfr_id);
        break;

    case PMBUS_MFR_MODEL:                 /* R/W block */
        pmbus_send_string(pmdev, s->mfr_model);
        break;

    case PMBUS_MFR_REVISION:              /* R/W block */
        pmbus_send_string(pmdev, s->mfr_rev);
        break;

    case PMBUS_IC_DEVICE_ID:
        pmbus_send(pmdev, adm1266_ic_device_id, sizeof(adm1266_ic_device_id));
        break;

    case PMBUS_IC_DEVICE_REV:
        pmbus_send(pmdev, adm1266_ic_device_rev, sizeof(adm1266_ic_device_rev));
        break;

    default:
        qemu_log_mask(LOG_UNIMP,
                      "%s: reading from unimplemented register: 0x%02x\n",
                      __func__, pmdev->code);
        return 0xFF;
    }

    return 0;
}

static int adm1266_write_data(PMBusDevice *pmdev, const uint8_t *buf,
                              uint8_t len)
{
    ADM1266State *s = ADM1266(pmdev);

    switch (pmdev->code) {
    case PMBUS_MFR_ID:                    /* R/W block */
        pmbus_receive_block(pmdev, (uint8_t *)s->mfr_id, sizeof(s->mfr_id));
        break;

    case PMBUS_MFR_MODEL:                 /* R/W block */
        pmbus_receive_block(pmdev, (uint8_t *)s->mfr_model,
                            sizeof(s->mfr_model));
        break;

    case PMBUS_MFR_REVISION:               /* R/W block*/
        pmbus_receive_block(pmdev, (uint8_t *)s->mfr_rev, sizeof(s->mfr_rev));
        break;

    case ADM1266_SET_RTC:   /* do nothing */
        break;

    default:
        qemu_log_mask(LOG_UNIMP,
                      "%s: writing to unimplemented register: 0x%02x\n",
                      __func__, pmdev->code);
        break;
    }
    return 0;
}

static void adm1266_get(Object *obj, Visitor *v, const char *name, void *opaque,
                        Error **errp)
{
    uint16_t value;
    PMBusDevice *pmdev = PMBUS_DEVICE(obj);
    PMBusVoutMode *mode = (PMBusVoutMode *)&pmdev->pages[0].vout_mode;

    if (strcmp(name, "vout") == 0) {
        value = pmbus_linear_mode2data(*(uint16_t *)opaque, mode->exp);
    } else {
        value = *(uint16_t *)opaque;
    }

    visit_type_uint16(v, name, &value, errp);
}

static void adm1266_set(Object *obj, Visitor *v, const char *name, void *opaque,
                        Error **errp)
{
    uint16_t *internal = opaque;
    uint16_t value;
    PMBusDevice *pmdev = PMBUS_DEVICE(obj);
    PMBusVoutMode *mode = (PMBusVoutMode *)&pmdev->pages[0].vout_mode;

    if (!visit_type_uint16(v, name, &value, errp)) {
        return;
    }

    *internal = pmbus_data2linear_mode(value, mode->exp);
    pmbus_check_limits(pmdev);
}

static const VMStateDescription vmstate_adm1266 = {
    .name = "ADM1266",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (const VMStateField[]){
        VMSTATE_PMBUS_DEVICE(parent, ADM1266State),
        VMSTATE_END_OF_LIST()
    }
};

static void adm1266_init(Object *obj)
{
    PMBusDevice *pmdev = PMBUS_DEVICE(obj);
    uint64_t flags = PB_HAS_VOUT_MODE | PB_HAS_VOUT | PB_HAS_VOUT_MARGIN |
                     PB_HAS_VOUT_RATING | PB_HAS_STATUS_MFR_SPECIFIC;

    for (int i = 0; i < ADM1266_NUM_PAGES; i++) {
        pmbus_page_config(pmdev, i, flags);

        object_property_add(obj, "vout[*]", "uint16",
                            adm1266_get,
                            adm1266_set, NULL, &pmdev->pages[i].read_vout);
    }
}

static void adm1266_class_init(ObjectClass *klass, void *data)
{
    ResettableClass *rc = RESETTABLE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);
    PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);

    dc->desc = "Analog Devices ADM1266 Hot Swap controller";
    dc->vmsd = &vmstate_adm1266;
    k->write_data = adm1266_write_data;
    k->receive_byte = adm1266_read_byte;
    k->device_num_pages = 17;

    rc->phases.exit = adm1266_exit_reset;
}

static const TypeInfo adm1266_info = {
    .name = TYPE_ADM1266,
    .parent = TYPE_PMBUS_DEVICE,
    .instance_size = sizeof(ADM1266State),
    .instance_init = adm1266_init,
    .class_init = adm1266_class_init,
};

static void adm1266_register_types(void)
{
    type_register_static(&adm1266_info);
}

type_init(adm1266_register_types)
