/*
 * Syborg pointing device (mouse/touchscreen)
 *
 * Copyright (c) 2008 CodeSourcery
 *
 * 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 "sysbus.h"
#include "console.h"
#include "syborg.h"

enum {
    POINTER_ID          = 0,
    POINTER_LATCH       = 1,
    POINTER_FIFO_COUNT  = 2,
    POINTER_X           = 3,
    POINTER_Y           = 4,
    POINTER_Z           = 5,
    POINTER_BUTTONS     = 6,
    POINTER_INT_ENABLE  = 7,
    POINTER_FIFO_SIZE   = 8
};

typedef struct {
    int x, y, z, pointer_buttons;
} event_data;

typedef struct {
    SysBusDevice busdev;
    int int_enabled;
    uint32_t fifo_size;
    event_data *event_fifo;
    int read_pos, read_count;
    qemu_irq irq;
    uint32_t absolute;
} SyborgPointerState;

static void syborg_pointer_update(SyborgPointerState *s)
{
    qemu_set_irq(s->irq, s->read_count && s->int_enabled);
}

static uint32_t syborg_pointer_read(void *opaque, target_phys_addr_t offset)
{
    SyborgPointerState *s = (SyborgPointerState *)opaque;

    offset &= 0xfff;
    switch (offset >> 2) {
    case POINTER_ID:
        return s->absolute ? SYBORG_ID_TOUCHSCREEN : SYBORG_ID_MOUSE;
    case POINTER_FIFO_COUNT:
        return s->read_count;
    case POINTER_X:
        return s->event_fifo[s->read_pos].x;
    case POINTER_Y:
        return s->event_fifo[s->read_pos].y;
    case POINTER_Z:
        return s->event_fifo[s->read_pos].z;
    case POINTER_BUTTONS:
        return s->event_fifo[s->read_pos].pointer_buttons;
    case POINTER_INT_ENABLE:
        return s->int_enabled;
    case POINTER_FIFO_SIZE:
        return s->fifo_size;
    default:
        cpu_abort(cpu_single_env, "syborg_pointer_read: Bad offset %x\n",
                  (int)offset);
        return 0;
    }
}

static void syborg_pointer_write(void *opaque, target_phys_addr_t offset,
                                 uint32_t value)
{
    SyborgPointerState *s = (SyborgPointerState *)opaque;

    offset &= 0xfff;
    switch (offset >> 2) {
    case POINTER_LATCH:
        if (s->read_count > 0) {
            s->read_count--;
            if (++s->read_pos == s->fifo_size)
                s->read_pos = 0;
        }
        break;
    case POINTER_INT_ENABLE:
        s->int_enabled = value;
        break;
    default:
        cpu_abort(cpu_single_env, "syborg_pointer_write: Bad offset %x\n",
                  (int)offset);
    }
    syborg_pointer_update(s);
}

static CPUReadMemoryFunc * const syborg_pointer_readfn[] = {
   syborg_pointer_read,
   syborg_pointer_read,
   syborg_pointer_read
};

static CPUWriteMemoryFunc * const syborg_pointer_writefn[] = {
   syborg_pointer_write,
   syborg_pointer_write,
   syborg_pointer_write
};

static void syborg_pointer_event(void *opaque, int dx, int dy, int dz,
                                 int buttons_state)
{
    SyborgPointerState *s = (SyborgPointerState *)opaque;
    int slot = s->read_pos + s->read_count;

    /* This first FIFO entry is used to store current register state.  */
    if (s->read_count < s->fifo_size - 1) {
        s->read_count++;
        slot++;
    }

    if (slot >= s->fifo_size)
          slot -= s->fifo_size;

    if (s->read_count == s->fifo_size && !s->absolute) {
        /* Merge existing entries.  */
        s->event_fifo[slot].x += dx;
        s->event_fifo[slot].y += dy;
        s->event_fifo[slot].z += dz;
    } else {
        s->event_fifo[slot].x = dx;
        s->event_fifo[slot].y = dy;
        s->event_fifo[slot].z = dz;
    }
    s->event_fifo[slot].pointer_buttons = buttons_state;

    syborg_pointer_update(s);
}

static void syborg_pointer_save(QEMUFile *f, void *opaque)
{
    SyborgPointerState *s = (SyborgPointerState *)opaque;
    int i;

    qemu_put_be32(f, s->fifo_size);
    qemu_put_be32(f, s->absolute);
    qemu_put_be32(f, s->int_enabled);
    qemu_put_be32(f, s->read_pos);
    qemu_put_be32(f, s->read_count);
    for (i = 0; i < s->fifo_size; i++) {
        qemu_put_be32(f, s->event_fifo[i].x);
        qemu_put_be32(f, s->event_fifo[i].y);
        qemu_put_be32(f, s->event_fifo[i].z);
        qemu_put_be32(f, s->event_fifo[i].pointer_buttons);
    }
}

static int syborg_pointer_load(QEMUFile *f, void *opaque, int version_id)
{
    SyborgPointerState *s = (SyborgPointerState *)opaque;
    uint32_t val;
    int i;

    if (version_id != 1)
        return -EINVAL;

    val = qemu_get_be32(f);
    if (val != s->fifo_size)
        return -EINVAL;

    val = qemu_get_be32(f);
    if (val != s->absolute)
        return -EINVAL;

    s->int_enabled = qemu_get_be32(f);
    s->read_pos = qemu_get_be32(f);
    s->read_count = qemu_get_be32(f);
    for (i = 0; i < s->fifo_size; i++) {
        s->event_fifo[i].x = qemu_get_be32(f);
        s->event_fifo[i].y = qemu_get_be32(f);
        s->event_fifo[i].z = qemu_get_be32(f);
        s->event_fifo[i].pointer_buttons = qemu_get_be32(f);
    }
    return 0;
}

static int syborg_pointer_init(SysBusDevice *dev)
{
    SyborgPointerState *s = FROM_SYSBUS(SyborgPointerState, dev);
    int iomemtype;

    sysbus_init_irq(dev, &s->irq);
    iomemtype = cpu_register_io_memory(syborg_pointer_readfn,
				       syborg_pointer_writefn, s);
    sysbus_init_mmio(dev, 0x1000, iomemtype);

    if (s->fifo_size <= 0) {
        fprintf(stderr, "syborg_pointer: fifo too small\n");
        s->fifo_size = 16;
    }
    s->event_fifo = qemu_mallocz(s->fifo_size * sizeof(s->event_fifo[0]));

    qemu_add_mouse_event_handler(syborg_pointer_event, s, s->absolute,
                                 "Syborg Pointer");

    register_savevm("syborg_pointer", -1, 1,
                    syborg_pointer_save, syborg_pointer_load, s);
    return 0;
}

static SysBusDeviceInfo syborg_pointer_info = {
    .init = syborg_pointer_init,
    .qdev.name  = "syborg,pointer",
    .qdev.size  = sizeof(SyborgPointerState),
    .qdev.props = (Property[]) {
        DEFINE_PROP_UINT32("fifo-size", SyborgPointerState, fifo_size, 16),
        DEFINE_PROP_UINT32("absolute",  SyborgPointerState, absolute,   1),
        DEFINE_PROP_END_OF_LIST(),
    }
};

static void syborg_pointer_register_devices(void)
{
    sysbus_register_withprop(&syborg_pointer_info);
}

device_init(syborg_pointer_register_devices)
