/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "migration/qemu-file.h"
#include "hw/android/goldfish/device.h"
#include "hw/android/goldfish/vmem.h"
#include "hw/hw.h"

enum {
    SW_NAME_LEN     = 0x00,
    SW_NAME_PTR     = 0x04,
    SW_FLAGS        = 0x08,
    SW_STATE        = 0x0c,
    SW_INT_STATUS   = 0x10,
    SW_INT_ENABLE   = 0x14,

    SW_FLAGS_OUTPUT = 1U << 0
};


struct switch_state {
    struct goldfish_device dev;
    char *name;
    uint32_t state;
    uint32_t state_changed : 1;
    uint32_t int_enable : 1;
    uint32_t (*writefn)(void *opaque, uint32_t state);
    void *writeopaque;
};

#define  GOLDFISH_SWITCH_SAVE_VERSION  1

static void  goldfish_switch_save(QEMUFile*  f, void*  opaque)
{
    struct switch_state*  s = opaque;

    qemu_put_be32(f, s->state);
    qemu_put_byte(f, s->state_changed);
    qemu_put_byte(f, s->int_enable);
}

static int  goldfish_switch_load(QEMUFile*  f, void*  opaque, int  version_id)
{
    struct switch_state*  s = opaque;

    if (version_id != GOLDFISH_SWITCH_SAVE_VERSION)
        return -1;

    s->state         = qemu_get_be32(f);
    s->state_changed = qemu_get_byte(f);
    s->int_enable    = qemu_get_byte(f);

    return 0;
}

static uint32_t goldfish_switch_read(void *opaque, hwaddr offset)
{
    struct switch_state *s = (struct switch_state *)opaque;

    //printf("goldfish_switch_read %x %x\n", offset, size);

    switch (offset) {
        case SW_NAME_LEN:
            return strlen(s->name);
        case SW_FLAGS:
            return s->writefn ? SW_FLAGS_OUTPUT : 0;
        case SW_STATE:
            return s->state;
        case SW_INT_STATUS:
            if(s->state_changed && s->int_enable) {
                s->state_changed = 0;
                goldfish_device_set_irq(&s->dev, 0, 0);
                return 1;
            }
            return 0;
    default:
        cpu_abort (cpu_single_env, "goldfish_switch_read: Bad offset %x\n", offset);
        return 0;
    }
}

static void goldfish_switch_write(void *opaque, hwaddr offset, uint32_t value)
{
    struct switch_state *s = (struct switch_state *)opaque;

    //printf("goldfish_switch_read %x %x %x\n", offset, value, size);

    switch(offset) {
        case SW_NAME_PTR:
            safe_memory_rw_debug(cpu_single_env, value, (void*)s->name, strlen(s->name), 1);
            break;

        case SW_STATE:
            if(s->writefn) {
                uint32_t new_state;
                new_state = s->writefn(s->writeopaque, value);
                if(new_state != s->state) {
                    goldfish_switch_set_state(s, new_state);
                }
            }
            else
                cpu_abort (cpu_single_env, "goldfish_switch_write: write to SW_STATE on input\n");
            break;

        case SW_INT_ENABLE:
            value &= 1;
            if(s->state_changed && s->int_enable != value)
                goldfish_device_set_irq(&s->dev, 0, value);
            s->int_enable = value;
            break;

        default:
            cpu_abort (cpu_single_env, "goldfish_switch_write: Bad offset %x\n", offset);
    }
}

static CPUReadMemoryFunc *goldfish_switch_readfn[] = {
    goldfish_switch_read,
    goldfish_switch_read,
    goldfish_switch_read
};

static CPUWriteMemoryFunc *goldfish_switch_writefn[] = {
    goldfish_switch_write,
    goldfish_switch_write,
    goldfish_switch_write
};

void goldfish_switch_set_state(void *opaque, uint32_t state)
{
    struct switch_state *s = opaque;
    s->state_changed = 1;
    s->state = state;
    if(s->int_enable)
        goldfish_device_set_irq(&s->dev, 0, 1);
}

void *goldfish_switch_add(char *name, uint32_t (*writefn)(void *opaque, uint32_t state), void *writeopaque, int id)
{
    int ret;
    struct switch_state *s;

    s = g_malloc0(sizeof(*s));
    s->dev.name = "goldfish-switch";
    s->dev.id = id;
    s->dev.size = 0x1000;
    s->dev.irq_count = 1;
    s->name = name;
    s->writefn = writefn;
    s->writeopaque = writeopaque;


    ret = goldfish_device_add(&s->dev, goldfish_switch_readfn, goldfish_switch_writefn, s);
    if(ret) {
        g_free(s);
        return NULL;
    }

    register_savevm( "goldfish_switch", 0, GOLDFISH_SWITCH_SAVE_VERSION,
                     goldfish_switch_save, goldfish_switch_load, s);

    return s;
}

