/*
 * MAX7310 8-port GPIO expansion chip.
 *
 * Copyright (c) 2006 Openedhand Ltd.
 * Written by Andrzej Zaborowski <balrog@zabor.org>
 *
 * This file is licensed under GNU GPL.
 */

#include "hw.h"
#include "i2c.h"

struct max7310_s {
    i2c_slave i2c;
    int i2c_command_byte;
    int len;

    uint8_t level;
    uint8_t direction;
    uint8_t polarity;
    uint8_t status;
    uint8_t command;
    qemu_irq handler[8];
    qemu_irq *gpio_in;
};

void max7310_reset(i2c_slave *i2c)
{
    struct max7310_s *s = (struct max7310_s *) i2c;
    s->level &= s->direction;
    s->direction = 0xff;
    s->polarity = 0xf0;
    s->status = 0x01;
    s->command = 0x00;
}

static int max7310_rx(i2c_slave *i2c)
{
    struct max7310_s *s = (struct max7310_s *) i2c;

    switch (s->command) {
    case 0x00:	/* Input port */
        return s->level ^ s->polarity;
        break;

    case 0x01:	/* Output port */
        return s->level & ~s->direction;
        break;

    case 0x02:	/* Polarity inversion */
        return s->polarity;

    case 0x03:	/* Configuration */
        return s->direction;

    case 0x04:	/* Timeout */
        return s->status;
        break;

    case 0xff:	/* Reserved */
        return 0xff;

    default:
#ifdef VERBOSE
        printf("%s: unknown register %02x\n", __FUNCTION__, s->command);
#endif
        break;
    }
    return 0xff;
}

static int max7310_tx(i2c_slave *i2c, uint8_t data)
{
    struct max7310_s *s = (struct max7310_s *) i2c;
    uint8_t diff;
    int line;

    if (s->len ++ > 1) {
#ifdef VERBOSE
        printf("%s: message too long (%i bytes)\n", __FUNCTION__, s->len);
#endif
        return 1;
    }

    if (s->i2c_command_byte) {
        s->command = data;
        s->i2c_command_byte = 0;
        return 0;
    }

    switch (s->command) {
    case 0x01:	/* Output port */
        for (diff = (data ^ s->level) & ~s->direction; diff;
                        diff &= ~(1 << line)) {
            line = ffs(diff) - 1;
            if (s->handler[line])
                qemu_set_irq(s->handler[line], (data >> line) & 1);
        }
        s->level = (s->level & s->direction) | (data & ~s->direction);
        break;

    case 0x02:	/* Polarity inversion */
        s->polarity = data;
        break;

    case 0x03:	/* Configuration */
        s->level &= ~(s->direction ^ data);
        s->direction = data;
        break;

    case 0x04:	/* Timeout */
        s->status = data;
        break;

    case 0x00:	/* Input port - ignore writes */
	break;
    default:
#ifdef VERBOSE
        printf("%s: unknown register %02x\n", __FUNCTION__, s->command);
#endif
        return 1;
    }

    return 0;
}

static void max7310_event(i2c_slave *i2c, enum i2c_event event)
{
    struct max7310_s *s = (struct max7310_s *) i2c;
    s->len = 0;

    switch (event) {
    case I2C_START_SEND:
        s->i2c_command_byte = 1;
        break;
    case I2C_FINISH:
        if (s->len == 1)
#ifdef VERBOSE
            printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len);
#endif
        break;
    default:
        break;
    }
}

static void max7310_save(QEMUFile *f, void *opaque)
{
    struct max7310_s *s = (struct max7310_s *) opaque;

    qemu_put_be32(f, s->i2c_command_byte);
    qemu_put_be32(f, s->len);

    qemu_put_8s(f, &s->level);
    qemu_put_8s(f, &s->direction);
    qemu_put_8s(f, &s->polarity);
    qemu_put_8s(f, &s->status);
    qemu_put_8s(f, &s->command);

    i2c_slave_save(f, &s->i2c);
}

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

    s->i2c_command_byte = qemu_get_be32(f);
    s->len = qemu_get_be32(f);

    qemu_get_8s(f, &s->level);
    qemu_get_8s(f, &s->direction);
    qemu_get_8s(f, &s->polarity);
    qemu_get_8s(f, &s->status);
    qemu_get_8s(f, &s->command);

    i2c_slave_load(f, &s->i2c);
    return 0;
}

static int max7310_iid = 0;

static void max7310_gpio_set(void *opaque, int line, int level)
{
    struct max7310_s *s = (struct max7310_s *) opaque;
    if (line >= sizeof(s->handler) / sizeof(*s->handler) || line  < 0)
        hw_error("bad GPIO line");

    if (level)
        s->level |= s->direction & (1 << line);
    else
        s->level &= ~(s->direction & (1 << line));
}

/* MAX7310 is SMBus-compatible (can be used with only SMBus protocols),
 * but also accepts sequences that are not SMBus so return an I2C device.  */
struct i2c_slave *max7310_init(i2c_bus *bus)
{
    struct max7310_s *s = (struct max7310_s *)
            i2c_slave_init(bus, 0, sizeof(struct max7310_s));
    s->i2c.event = max7310_event;
    s->i2c.recv = max7310_rx;
    s->i2c.send = max7310_tx;
    s->gpio_in = qemu_allocate_irqs(max7310_gpio_set, s,
                    sizeof(s->handler) / sizeof(*s->handler));

    max7310_reset(&s->i2c);

    register_savevm("max7310", max7310_iid ++, 0,
                    max7310_save, max7310_load, s);

    return &s->i2c;
}

qemu_irq *max7310_gpio_in_get(i2c_slave *i2c)
{
    struct max7310_s *s = (struct max7310_s *) i2c;
    return s->gpio_in;
}

void max7310_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler)
{
    struct max7310_s *s = (struct max7310_s *) i2c;
    if (line >= sizeof(s->handler) / sizeof(*s->handler) || line  < 0)
        hw_error("bad GPIO line");

    s->handler[line] = handler;
}
