/*
 * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
 *
 * Copyright (c) 2006 Openedhand Ltd.
 * Written by Andrzej Zaborowski <balrog@zabor.org>
 *
 * This code is licensed under the GPLv2.
 */

#include "hw.h"
#include "pcmcia.h"
#include "pxa.h"

struct pxa2xx_pcmcia_s {
    struct pcmcia_socket_s slot;
    struct pcmcia_card_s *card;

    qemu_irq irq;
    qemu_irq cd_irq;
};

static uint32_t pxa2xx_pcmcia_common_read(void *opaque,
                target_phys_addr_t offset)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;

    if (s->slot.attached) {
        return s->card->common_read(s->card->state, offset);
    }

    return 0;
}

static void pxa2xx_pcmcia_common_write(void *opaque,
                target_phys_addr_t offset, uint32_t value)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;

    if (s->slot.attached) {
        s->card->common_write(s->card->state, offset, value);
    }
}

static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
                target_phys_addr_t offset)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;

    if (s->slot.attached) {
        return s->card->attr_read(s->card->state, offset);
    }

    return 0;
}

static void pxa2xx_pcmcia_attr_write(void *opaque,
                target_phys_addr_t offset, uint32_t value)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;

    if (s->slot.attached) {
        s->card->attr_write(s->card->state, offset, value);
    }
}

static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
                target_phys_addr_t offset)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;

    if (s->slot.attached) {
        return s->card->io_read(s->card->state, offset);
    }

    return 0;
}

static void pxa2xx_pcmcia_io_write(void *opaque,
                target_phys_addr_t offset, uint32_t value)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;

    if (s->slot.attached) {
        s->card->io_write(s->card->state, offset, value);
    }
}

static CPUReadMemoryFunc *pxa2xx_pcmcia_common_readfn[] = {
    pxa2xx_pcmcia_common_read,
    pxa2xx_pcmcia_common_read,
    pxa2xx_pcmcia_common_read,
};

static CPUWriteMemoryFunc *pxa2xx_pcmcia_common_writefn[] = {
    pxa2xx_pcmcia_common_write,
    pxa2xx_pcmcia_common_write,
    pxa2xx_pcmcia_common_write,
};

static CPUReadMemoryFunc *pxa2xx_pcmcia_attr_readfn[] = {
    pxa2xx_pcmcia_attr_read,
    pxa2xx_pcmcia_attr_read,
    pxa2xx_pcmcia_attr_read,
};

static CPUWriteMemoryFunc *pxa2xx_pcmcia_attr_writefn[] = {
    pxa2xx_pcmcia_attr_write,
    pxa2xx_pcmcia_attr_write,
    pxa2xx_pcmcia_attr_write,
};

static CPUReadMemoryFunc *pxa2xx_pcmcia_io_readfn[] = {
    pxa2xx_pcmcia_io_read,
    pxa2xx_pcmcia_io_read,
    pxa2xx_pcmcia_io_read,
};

static CPUWriteMemoryFunc *pxa2xx_pcmcia_io_writefn[] = {
    pxa2xx_pcmcia_io_write,
    pxa2xx_pcmcia_io_write,
    pxa2xx_pcmcia_io_write,
};

static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
    if (!s->irq)
        return;

    qemu_set_irq(s->irq, level);
}

struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base)
{
    int iomemtype;
    struct pxa2xx_pcmcia_s *s;

    s = (struct pxa2xx_pcmcia_s *)
            qemu_mallocz(sizeof(struct pxa2xx_pcmcia_s));

    /* Socket I/O Memory Space */
    iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_io_readfn,
                    pxa2xx_pcmcia_io_writefn, s);
    cpu_register_physical_memory(base | 0x00000000, 0x04000000, iomemtype);

    /* Then next 64 MB is reserved */

    /* Socket Attribute Memory Space */
    iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_attr_readfn,
                    pxa2xx_pcmcia_attr_writefn, s);
    cpu_register_physical_memory(base | 0x08000000, 0x04000000, iomemtype);

    /* Socket Common Memory Space */
    iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_common_readfn,
                    pxa2xx_pcmcia_common_writefn, s);
    cpu_register_physical_memory(base | 0x0c000000, 0x04000000, iomemtype);

    if (base == 0x30000000)
        s->slot.slot_string = "PXA PC Card Socket 1";
    else
        s->slot.slot_string = "PXA PC Card Socket 0";
    s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
    pcmcia_socket_register(&s->slot);

    return s;
}

/* Insert a new card into a slot */
int pxa2xx_pcmcia_attach(void *opaque, struct pcmcia_card_s *card)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
    if (s->slot.attached)
        return -EEXIST;

    if (s->cd_irq) {
        qemu_irq_raise(s->cd_irq);
    }

    s->card = card;

    s->slot.attached = 1;
    s->card->slot = &s->slot;
    s->card->attach(s->card->state);

    return 0;
}

/* Eject card from the slot */
int pxa2xx_pcmcia_dettach(void *opaque)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
    if (!s->slot.attached)
        return -ENOENT;

    s->card->detach(s->card->state);
    s->card->slot = 0;
    s->card = 0;

    s->slot.attached = 0;

    if (s->irq)
        qemu_irq_lower(s->irq);
    if (s->cd_irq)
        qemu_irq_lower(s->cd_irq);

    return 0;
}

/* Who to notify on card events */
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
{
    struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
    s->irq = irq;
    s->cd_irq = cd_irq;
}
