/* vim:set shiftwidth=4 ts=4 et: */
/*
 * PXA255 Sharp Zaurus SL-6000 PDA platform
 *
 * Copyright (c) 2008 Dmitry Baryshkov
 *
 * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
 * This code is licensed under the GNU GPL v2.
 */

#include "hw.h"
#include "pxa.h"
#include "arm-misc.h"
#include "sysemu.h"
#include "devices.h"
#include "sharpsl.h"
#include "pcmcia.h"
#include "block.h"
#include "boards.h"
#include "i2c.h"
#include "ssi.h"

#define TOSA_RAM    0x04000000
#define TOSA_ROM	0x00800000

#define TOSA_GPIO_nSD_DETECT	(9)
#define TOSA_GPIO_ON_RESET		(19)
#define TOSA_GPIO_CF_IRQ		(21)	/* CF slot0 Ready */
#define TOSA_GPIO_CF_CD			(13)
#define TOSA_GPIO_TC6393XB_INT  (15)
#define TOSA_GPIO_JC_CF_IRQ		(36)	/* CF slot1 Ready */

#define TOSA_SCOOP_GPIO_BASE	1
#define TOSA_GPIO_IR_POWERDWN	(TOSA_SCOOP_GPIO_BASE + 2)
#define TOSA_GPIO_SD_WP			(TOSA_SCOOP_GPIO_BASE + 3)
#define TOSA_GPIO_PWR_ON		(TOSA_SCOOP_GPIO_BASE + 4)

#define TOSA_SCOOP_JC_GPIO_BASE		1
#define TOSA_GPIO_BT_LED		(TOSA_SCOOP_JC_GPIO_BASE + 0)
#define TOSA_GPIO_NOTE_LED		(TOSA_SCOOP_JC_GPIO_BASE + 1)
#define TOSA_GPIO_CHRG_ERR_LED		(TOSA_SCOOP_JC_GPIO_BASE + 2)
#define TOSA_GPIO_TC6393XB_L3V_ON	(TOSA_SCOOP_JC_GPIO_BASE + 5)
#define TOSA_GPIO_WLAN_LED		(TOSA_SCOOP_JC_GPIO_BASE + 7)

#define	DAC_BASE	0x4e
#define DAC_CH1		0
#define DAC_CH2		1

static void tosa_microdrive_attach(PXA2xxState *cpu)
{
    PCMCIACardState *md;
    BlockDriverState *bs;
    DriveInfo *dinfo;

    dinfo = drive_get(IF_IDE, 0, 0);
    if (!dinfo)
        return;
    bs = dinfo->bdrv;
    if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
        md = dscm1xxxx_init(dinfo);
        pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
    }
}

static void tosa_out_switch(void *opaque, int line, int level)
{
    switch (line) {
        case 0:
            fprintf(stderr, "blue LED %s.\n", level ? "on" : "off");
            break;
        case 1:
            fprintf(stderr, "green LED %s.\n", level ? "on" : "off");
            break;
        case 2:
            fprintf(stderr, "amber LED %s.\n", level ? "on" : "off");
            break;
        case 3:
            fprintf(stderr, "wlan LED %s.\n", level ? "on" : "off");
            break;
        default:
            fprintf(stderr, "Uhandled out event: %d = %d\n", line, level);
            break;
    }
}


static void tosa_gpio_setup(PXA2xxState *cpu,
                ScoopInfo *scp0,
                ScoopInfo *scp1,
                TC6393xbState *tmio)
{
    qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4);
    /* MMC/SD host */
    pxa2xx_mmci_handlers(cpu->mmc,
                    scoop_gpio_in_get(scp0)[TOSA_GPIO_SD_WP],
                    qemu_irq_invert(pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_nSD_DETECT]));

    /* Handle reset */
    pxa2xx_gpio_out_set(cpu->gpio, TOSA_GPIO_ON_RESET, cpu->reset);

    /* PCMCIA signals: card's IRQ and Card-Detect */
    pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
                        pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_CF_IRQ],
                        pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_CF_CD]);

    pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1],
                        pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_JC_CF_IRQ],
                        NULL);

    scoop_gpio_out_set(scp1, TOSA_GPIO_BT_LED, outsignals[0]);
    scoop_gpio_out_set(scp1, TOSA_GPIO_NOTE_LED, outsignals[1]);
    scoop_gpio_out_set(scp1, TOSA_GPIO_CHRG_ERR_LED, outsignals[2]);
    scoop_gpio_out_set(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]);

    scoop_gpio_out_set(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio));
}

static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
{
    fprintf(stderr, "TG: %d %02x\n", value >> 5, value & 0x1f);
    return 0;
}

static int tosa_ssp_init(SSISlave *dev)
{
    /* Nothing to do.  */
    return 0;
}

typedef struct {
    i2c_slave i2c;
    int len;
    char buf[3];
} TosaDACState;

static int tosa_dac_send(i2c_slave *i2c, uint8_t data)
{
    TosaDACState *s = FROM_I2C_SLAVE(TosaDACState, i2c);
    s->buf[s->len] = data;
    if (s->len ++ > 2) {
#ifdef VERBOSE
        fprintf(stderr, "%s: message too long (%i bytes)\n", __FUNCTION__, s->len);
#endif
        return 1;
    }

    if (s->len == 2) {
        fprintf(stderr, "dac: channel %d value 0x%02x\n",
                s->buf[0], s->buf[1]);
    }

    return 0;
}

static void tosa_dac_event(i2c_slave *i2c, enum i2c_event event)
{
    TosaDACState *s = FROM_I2C_SLAVE(TosaDACState, i2c);
    s->len = 0;
    switch (event) {
    case I2C_START_SEND:
        break;
    case I2C_START_RECV:
        printf("%s: recv not supported!!!\n", __FUNCTION__);
        break;
    case I2C_FINISH:
#ifdef VERBOSE
        if (s->len < 2)
            printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len);
        if (s->len > 2)
            printf("%s: message too long\n", __FUNCTION__);
#endif
        break;
    default:
        break;
    }
}

static int tosa_dac_recv(i2c_slave *s)
{
    printf("%s: recv not supported!!!\n", __FUNCTION__);
    return -1;
}

static int tosa_dac_init(i2c_slave *i2c)
{
    /* Nothing to do.  */
    return 0;
}

static void tosa_tg_init(PXA2xxState *cpu)
{
    i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
    i2c_create_slave(bus, "tosa_dac", DAC_BASE);
    ssi_create_slave(cpu->ssp[1], "tosa-ssp");
}


static struct arm_boot_info tosa_binfo = {
    .loader_start = PXA2XX_SDRAM_BASE,
    .ram_size = 0x04000000,
};

static void tosa_init(ram_addr_t ram_size,
                const char *boot_device,
                const char *kernel_filename, const char *kernel_cmdline,
                const char *initrd_filename, const char *cpu_model)
{
    PXA2xxState *cpu;
    TC6393xbState *tmio;
    ScoopInfo *scp0, *scp1;

    if (!cpu_model)
        cpu_model = "pxa255";

    cpu = pxa255_init(tosa_binfo.ram_size);

    cpu_register_physical_memory(0, TOSA_ROM,
                    qemu_ram_alloc(TOSA_ROM) | IO_MEM_ROM);

    tmio = tc6393xb_init(0x10000000,
            pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_TC6393XB_INT]);

    scp0 = scoop_init(cpu, 0, 0x08800000);
    scp1 = scoop_init(cpu, 1, 0x14800040);

    tosa_gpio_setup(cpu, scp0, scp1, tmio);

    tosa_microdrive_attach(cpu);

    tosa_tg_init(cpu);

    /* Setup initial (reset) machine state */
    cpu->env->regs[15] = tosa_binfo.loader_start;

    tosa_binfo.kernel_filename = kernel_filename;
    tosa_binfo.kernel_cmdline = kernel_cmdline;
    tosa_binfo.initrd_filename = initrd_filename;
    tosa_binfo.board_id = 0x208;
    arm_load_kernel(cpu->env, &tosa_binfo);
    sl_bootparam_write(SL_PXA_PARAM_BASE);
}

static QEMUMachine tosapda_machine = {
    .name = "tosa",
    .desc = "Tosa PDA (PXA255)",
    .init = tosa_init,
};

static void tosapda_machine_init(void)
{
    qemu_register_machine(&tosapda_machine);
}

machine_init(tosapda_machine_init);

static I2CSlaveInfo tosa_dac_info = {
    .qdev.name = "tosa_dac",
    .qdev.size = sizeof(TosaDACState),
    .init = tosa_dac_init,
    .event = tosa_dac_event,
    .recv = tosa_dac_recv,
    .send = tosa_dac_send
};

static SSISlaveInfo tosa_ssp_info = {
    .qdev.name = "tosa-ssp",
    .qdev.size = sizeof(SSISlave),
    .init = tosa_ssp_init,
    .transfer = tosa_ssp_tansfer
};

static void tosa_register_devices(void)
{
    i2c_register_slave(&tosa_dac_info);
    ssi_register_slave(&tosa_ssp_info);
}

device_init(tosa_register_devices)
