/* 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 "cpu.h"
#include "migration/qemu-file.h"
#include "hw/android/goldfish/device.h"
#include "hw/hw.h"
#include "hw/power_supply.h"


enum {
	/* status register */
	BATTERY_INT_STATUS	    = 0x00,
	/* set this to enable IRQ */
	BATTERY_INT_ENABLE	    = 0x04,

	BATTERY_AC_ONLINE       = 0x08,
	BATTERY_STATUS          = 0x0C,
	BATTERY_HEALTH          = 0x10,
	BATTERY_PRESENT         = 0x14,
	BATTERY_CAPACITY        = 0x18,

	BATTERY_STATUS_CHANGED	= 1U << 0,
	AC_STATUS_CHANGED   	= 1U << 1,
	BATTERY_INT_MASK        = BATTERY_STATUS_CHANGED | AC_STATUS_CHANGED,
};


struct goldfish_battery_state {
    struct goldfish_device dev;
    // IRQs
    uint32_t int_status;
    // irq enable mask for int_status
    uint32_t int_enable;

    int ac_online;
    int status;
    int health;
    int present;
    int capacity;

    // the fields below are part of the device configuration
    // and don't need to be saved to / restored from snapshots.
    int hw_has_battery;
};

/* update this each time you update the battery_state struct */
#define  BATTERY_STATE_SAVE_VERSION  1

#define  QFIELD_STRUCT  struct goldfish_battery_state
QFIELD_BEGIN(goldfish_battery_fields)
    QFIELD_INT32(int_status),
    QFIELD_INT32(int_enable),
    QFIELD_INT32(ac_online),
    QFIELD_INT32(status),
    QFIELD_INT32(health),
    QFIELD_INT32(present),
    QFIELD_INT32(capacity),
QFIELD_END

static void  goldfish_battery_save(QEMUFile*  f, void* opaque)
{
    struct goldfish_battery_state*  s = opaque;

    qemu_put_struct(f, goldfish_battery_fields, s);
}

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

    if (version_id != BATTERY_STATE_SAVE_VERSION)
        return -1;

    return qemu_get_struct(f, goldfish_battery_fields, s);
}

static struct goldfish_battery_state *battery_state;

static uint32_t goldfish_battery_read(void *opaque, hwaddr offset)
{
    uint32_t ret;
    struct goldfish_battery_state *s = opaque;

    switch(offset) {
        case BATTERY_INT_STATUS:
            // return current buffer status flags
            ret = s->int_status & s->int_enable;
            if (ret) {
                goldfish_device_set_irq(&s->dev, 0, 0);
                s->int_status = 0;
            }
            return ret;

		case BATTERY_INT_ENABLE:
		    return s->int_enable;
		case BATTERY_AC_ONLINE:
		    return s->ac_online;
		case BATTERY_STATUS:
		    return s->status;
		case BATTERY_HEALTH:
		    return s->health;
		case BATTERY_PRESENT:
		    return s->present;
		case BATTERY_CAPACITY:
		    return s->capacity;

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

static void goldfish_battery_write(void *opaque, hwaddr offset, uint32_t val)
{
    struct goldfish_battery_state *s = opaque;

    switch(offset) {
        case BATTERY_INT_ENABLE:
            /* enable interrupts */
            s->int_enable = val;
//            s->int_status = (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY);
//            goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
            break;

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

static CPUReadMemoryFunc *goldfish_battery_readfn[] = {
    goldfish_battery_read,
    goldfish_battery_read,
    goldfish_battery_read
};


static CPUWriteMemoryFunc *goldfish_battery_writefn[] = {
    goldfish_battery_write,
    goldfish_battery_write,
    goldfish_battery_write
};

void goldfish_battery_init(int has_battery)
{
    struct goldfish_battery_state *s;

    s = (struct goldfish_battery_state *)g_malloc0(sizeof(*s));
    s->dev.name = "goldfish-battery";
    s->dev.base = 0;    // will be allocated dynamically
    s->dev.size = 0x1000;
    s->dev.irq_count = 1;

    // default values for the battery
    s->ac_online = 1;
    s->hw_has_battery = has_battery;
    if (has_battery) {
        s->status = POWER_SUPPLY_STATUS_CHARGING;
        s->health = POWER_SUPPLY_HEALTH_GOOD;
        s->present = 1;     // battery is present
        s->capacity = 50;   // 50% charged
    } else {
        s->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
        s->health = POWER_SUPPLY_HEALTH_DEAD;
        s->present = 0;
        s->capacity = 0;
    }

    battery_state = s;

    goldfish_device_add(&s->dev, goldfish_battery_readfn, goldfish_battery_writefn, s);

    register_savevm( "battery_state", 0, BATTERY_STATE_SAVE_VERSION,
                     goldfish_battery_save, goldfish_battery_load, s);
}

void goldfish_battery_set_prop(int ac, int property, int value)
{
    int new_status = (ac ? AC_STATUS_CHANGED : BATTERY_STATUS_CHANGED);

    if (!battery_state || !battery_state->hw_has_battery)
        return;

    if (ac) {
        switch (property) {
            case POWER_SUPPLY_PROP_ONLINE:
                battery_state->ac_online = value;
                break;
        }
    } else {
         switch (property) {
            case POWER_SUPPLY_PROP_STATUS:
                battery_state->status = value;
                break;
            case POWER_SUPPLY_PROP_HEALTH:
                battery_state->health = value;
                break;
            case POWER_SUPPLY_PROP_PRESENT:
                battery_state->present = value;
                break;
            case POWER_SUPPLY_PROP_CAPACITY:
                battery_state->capacity = value;
                break;
        }
    }

    if (new_status != battery_state->int_status) {
        battery_state->int_status |= new_status;
        goldfish_device_set_irq(&battery_state->dev, 0, (battery_state->int_status & battery_state->int_enable));
    }
}

void goldfish_battery_display(void (* callback)(void *data, const char* string), void *data)
{
    char          buffer[100];
    const char*   value;

    // Note: obviously, if there is no battery, the AC must always be on.
    snprintf(buffer, sizeof buffer, "AC: %s\r\n",
             (battery_state->ac_online) ? "online" : "offline");
    callback(data, buffer);

    switch (battery_state->status) {
        case POWER_SUPPLY_STATUS_CHARGING:
            value = "Charging";
            break;
        case POWER_SUPPLY_STATUS_DISCHARGING:
            value = "Discharging";
            break;
        case POWER_SUPPLY_STATUS_NOT_CHARGING:
            value = "Not charging";
            break;
        case POWER_SUPPLY_STATUS_FULL:
            value = "Full";
            break;
        default:
            value = "Unknown";
    }
    snprintf(buffer, sizeof buffer, "status: %s\r\n", value);
    callback(data, buffer);

    switch (battery_state->health) {
        case POWER_SUPPLY_HEALTH_GOOD:
            value = "Good";
            break;
        case POWER_SUPPLY_HEALTH_OVERHEAT:
            value = "Overhead";
            break;
        case POWER_SUPPLY_HEALTH_DEAD:
            value = "Dead";
            break;
        case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
            value = "Overvoltage";
            break;
        case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
            value = "Unspecified failure";
            break;
        default:
            value = "Unknown";
    }
    snprintf(buffer, sizeof buffer, "health: %s\r\n", value);
    callback(data, buffer);

    snprintf(buffer, sizeof buffer, "present: %s\r\n",
             (battery_state->present) ? "true" : "false");
    callback(data, buffer);

    snprintf(buffer, sizeof buffer, "capacity: %d\r\n", battery_state->capacity);
    callback(data, buffer);
}
