/*
 * PCM-3680i PCI CAN device (SJA1000 based) emulation
 *
 * Copyright (c) 2016 Deniz Eren (deniz.eren@icloud.com)
 *
 * Based on Kvaser PCI CAN device (SJA1000 based) emulation implemented by
 * Jin Yang and Pavel Pisa
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu/event_notifier.h"
#include "qemu/module.h"
#include "qemu/thread.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "chardev/char.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "net/can_emu.h"

#include "can_sja1000.h"

#define TYPE_CAN_PCI_DEV "pcm3680_pci"

#define PCM3680i_PCI_DEV(obj) \
    OBJECT_CHECK(Pcm3680iPCIState, (obj), TYPE_CAN_PCI_DEV)

/* the PCI device and vendor IDs */
#ifndef PCM3680i_PCI_VENDOR_ID1
#define PCM3680i_PCI_VENDOR_ID1     0x13fe
#endif

#ifndef PCM3680i_PCI_DEVICE_ID1
#define PCM3680i_PCI_DEVICE_ID1     0xc002
#endif

#define PCM3680i_PCI_SJA_COUNT     2
#define PCM3680i_PCI_SJA_RANGE     0x100

#define PCM3680i_PCI_BYTES_PER_SJA 0x20

typedef struct Pcm3680iPCIState {
    /*< private >*/
    PCIDevice       dev;
    /*< public >*/
    MemoryRegion    sja_io[PCM3680i_PCI_SJA_COUNT];

    CanSJA1000State sja_state[PCM3680i_PCI_SJA_COUNT];
    qemu_irq        irq;

    char            *model; /* The model that support, only SJA1000 now. */
    CanBusState     *canbus[PCM3680i_PCI_SJA_COUNT];
} Pcm3680iPCIState;

static void pcm3680i_pci_reset(DeviceState *dev)
{
    Pcm3680iPCIState *d = PCM3680i_PCI_DEV(dev);
    int i;

    for (i = 0; i < PCM3680i_PCI_SJA_COUNT; i++) {
        can_sja_hardware_reset(&d->sja_state[i]);
    }
}

static uint64_t pcm3680i_pci_sja1_io_read(void *opaque, hwaddr addr,
                                          unsigned size)
{
    Pcm3680iPCIState *d = opaque;
    CanSJA1000State *s = &d->sja_state[0];

    if (addr >= PCM3680i_PCI_BYTES_PER_SJA) {
        return 0;
    }

    return can_sja_mem_read(s, addr, size);
}

static void pcm3680i_pci_sja1_io_write(void *opaque, hwaddr addr,
                                       uint64_t data, unsigned size)
{
    Pcm3680iPCIState *d = opaque;
    CanSJA1000State *s = &d->sja_state[0];

    if (addr >= PCM3680i_PCI_BYTES_PER_SJA) {
        return;
    }

    can_sja_mem_write(s, addr, data, size);
}

static uint64_t pcm3680i_pci_sja2_io_read(void *opaque, hwaddr addr,
                                          unsigned size)
{
    Pcm3680iPCIState *d = opaque;
    CanSJA1000State *s = &d->sja_state[1];

    if (addr >= PCM3680i_PCI_BYTES_PER_SJA) {
        return 0;
    }

    return can_sja_mem_read(s, addr, size);
}

static void pcm3680i_pci_sja2_io_write(void *opaque, hwaddr addr, uint64_t data,
                             unsigned size)
{
    Pcm3680iPCIState *d = opaque;
    CanSJA1000State *s = &d->sja_state[1];

    if (addr >= PCM3680i_PCI_BYTES_PER_SJA) {
        return;
    }

    can_sja_mem_write(s, addr, data, size);
}

static const MemoryRegionOps pcm3680i_pci_sja1_io_ops = {
    .read = pcm3680i_pci_sja1_io_read,
    .write = pcm3680i_pci_sja1_io_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .max_access_size = 1,
    },
};

static const MemoryRegionOps pcm3680i_pci_sja2_io_ops = {
    .read = pcm3680i_pci_sja2_io_read,
    .write = pcm3680i_pci_sja2_io_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .max_access_size = 1,
    },
};

static void pcm3680i_pci_realize(PCIDevice *pci_dev, Error **errp)
{
    Pcm3680iPCIState *d = PCM3680i_PCI_DEV(pci_dev);
    uint8_t *pci_conf;
    int i;

    pci_conf = pci_dev->config;
    pci_conf[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */

    d->irq = pci_allocate_irq(&d->dev);

    for (i = 0; i < PCM3680i_PCI_SJA_COUNT; i++) {
        can_sja_init(&d->sja_state[i], d->irq);
    }

    for (i = 0; i < PCM3680i_PCI_SJA_COUNT; i++) {
        if (can_sja_connect_to_bus(&d->sja_state[i], d->canbus[i]) < 0) {
            error_setg(errp, "can_sja_connect_to_bus failed");
            return;
        }
    }

    memory_region_init_io(&d->sja_io[0], OBJECT(d), &pcm3680i_pci_sja1_io_ops,
                          d, "pcm3680i_pci-sja1", PCM3680i_PCI_SJA_RANGE);

    memory_region_init_io(&d->sja_io[1], OBJECT(d), &pcm3680i_pci_sja2_io_ops,
                          d, "pcm3680i_pci-sja2", PCM3680i_PCI_SJA_RANGE);

    for (i = 0; i < PCM3680i_PCI_SJA_COUNT; i++) {
        pci_register_bar(&d->dev, /*BAR*/ i, PCI_BASE_ADDRESS_SPACE_IO,
                         &d->sja_io[i]);
    }
}

static void pcm3680i_pci_exit(PCIDevice *pci_dev)
{
    Pcm3680iPCIState *d = PCM3680i_PCI_DEV(pci_dev);
    int i;

    for (i = 0; i < PCM3680i_PCI_SJA_COUNT; i++) {
        can_sja_disconnect(&d->sja_state[i]);
    }

    qemu_free_irq(d->irq);
}

static const VMStateDescription vmstate_pcm3680i_pci = {
    .name = "pcm3680i_pci",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(dev, Pcm3680iPCIState),
        VMSTATE_STRUCT(sja_state[0], Pcm3680iPCIState, 0,
                       vmstate_can_sja, CanSJA1000State),
        VMSTATE_STRUCT(sja_state[1], Pcm3680iPCIState, 0,
                       vmstate_can_sja, CanSJA1000State),
        VMSTATE_END_OF_LIST()
    }
};

static void pcm3680i_pci_instance_init(Object *obj)
{
    Pcm3680iPCIState *d = PCM3680i_PCI_DEV(obj);

    object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
                             (Object **)&d->canbus[0],
                             qdev_prop_allow_set_link_before_realize,
                             0, &error_abort);
    object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
                             (Object **)&d->canbus[1],
                             qdev_prop_allow_set_link_before_realize,
                             0, &error_abort);
}

static void pcm3680i_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->realize = pcm3680i_pci_realize;
    k->exit = pcm3680i_pci_exit;
    k->vendor_id = PCM3680i_PCI_VENDOR_ID1;
    k->device_id = PCM3680i_PCI_DEVICE_ID1;
    k->revision = 0x00;
    k->class_id = 0x000c09;
    k->subsystem_vendor_id = PCM3680i_PCI_VENDOR_ID1;
    k->subsystem_id = PCM3680i_PCI_DEVICE_ID1;
    dc->desc = "Pcm3680i PCICANx";
    dc->vmsd = &vmstate_pcm3680i_pci;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    dc->reset = pcm3680i_pci_reset;
}

static const TypeInfo pcm3680i_pci_info = {
    .name          = TYPE_CAN_PCI_DEV,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(Pcm3680iPCIState),
    .class_init    = pcm3680i_pci_class_init,
    .instance_init = pcm3680i_pci_instance_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static void pcm3680i_pci_register_types(void)
{
    type_register_static(&pcm3680i_pci_info);
}

type_init(pcm3680i_pci_register_types)
