All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 09/11] Goldfish: Added battery device.
@ 2011-08-22  9:39 Patrick Jackson
  0 siblings, 0 replies; only message in thread
From: Patrick Jackson @ 2011-08-22  9:39 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 13823 bytes --]

Signed-off-by: Patrick Jackson <PatrickSJackson@gmail.com>
---
 Makefile.target       |    1 +
 hw/android_arm.c      |    1 +
 hw/goldfish_battery.c |  247
+++++++++++++++++++++++++++++++++++++++++++++++++
 hw/goldfish_device.h  |    3 +
 hw/power_supply.h     |  109 ++++++++++++++++++++++
 5 files changed, 361 insertions(+), 0 deletions(-)
 create mode 100644 hw/goldfish_battery.c
 create mode 100644 hw/power_supply.h

diff --git a/Makefile.target b/Makefile.target
index b44f1be..593594b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -362,6 +362,7 @@ obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += android_arm.o goldfish_device.o goldfish_interrupt.o
goldfish_timer.o
 obj-arm-y += goldfish_tty.o goldfish_nand.o goldfish_fb.o goldfish_memlog.o
+obj-arm-y += goldfish_battery.o

 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
 obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
diff --git a/hw/android_arm.c b/hw/android_arm.c
index f617a45..3fffc93 100644
--- a/hw/android_arm.c
+++ b/hw/android_arm.c
@@ -67,6 +67,7 @@ static void android_arm_init_(ram_addr_t ram_size,

     goldfish_fb_create(gbus, 0);
     goldfish_memlog_create(gbus, 0xff006000);
+    goldfish_battery_create(gbus);
     goldfish_nand_create(gbus);

     info.ram_size        = ram_size;
diff --git a/hw/goldfish_battery.c b/hw/goldfish_battery.c
new file mode 100644
index 0000000..685b4aa
--- /dev/null
+++ b/hw/goldfish_battery.c
@@ -0,0 +1,247 @@
+/* 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 "goldfish_device.h"
+#include "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,
+};
+
+
+typedef struct GoldfishBatteryDevice {
+    GoldfishDevice 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;
+} GoldfishBatteryDevice;
+
+static uint32_t goldfish_battery_read(void *opaque, target_phys_addr_t
offset)
+{
+    uint32_t ret;
+    GoldfishBatteryDevice *s = (GoldfishBatteryDevice *)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, target_phys_addr_t offset,
uint32_t val)
+{
+    GoldfishBatteryDevice *s = (GoldfishBatteryDevice *)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_set_prop(void *opaque, int ac, int property, int
value)
+{
+    int new_status = (ac ? AC_STATUS_CHANGED : BATTERY_STATUS_CHANGED);
+    GoldfishBatteryDevice *s = (GoldfishBatteryDevice *)opaque;
+
+    if (ac) {
+        switch (property) {
+            case POWER_SUPPLY_PROP_ONLINE:
+                s->ac_online = value;
+                break;
+        }
+    } else {
+         switch (property) {
+            case POWER_SUPPLY_PROP_STATUS:
+                s->status = value;
+                break;
+            case POWER_SUPPLY_PROP_HEALTH:
+                s->health = value;
+                break;
+            case POWER_SUPPLY_PROP_PRESENT:
+                s->present = value;
+                break;
+            case POWER_SUPPLY_PROP_CAPACITY:
+                s->capacity = value;
+                break;
+        }
+    }
+
+    if (new_status != s->int_status) {
+        s->int_status |= new_status;
+        goldfish_device_set_irq(&s->dev, 0, (s->int_status &
s->int_enable));
+    }
+}
+
+void goldfish_battery_display(void *opaque, void (* callback)(void *data,
const char* string), void *data)
+{
+    GoldfishBatteryDevice *s = (GoldfishBatteryDevice *)opaque;
+    char          buffer[100];
+    const char*   value;
+
+    sprintf(buffer, "AC: %s\r\n", (s->ac_online ? "online" : "offline"));
+    callback(data, buffer);
+
+    switch (s->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";
+         break;
+    }
+    sprintf(buffer, "status: %s\r\n", value);
+    callback(data, buffer);
+
+    switch (s->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";
+         break;
+    }
+    sprintf(buffer, "health: %s\r\n", value);
+    callback(data, buffer);
+
+    sprintf(buffer, "present: %s\r\n", (s->present ? "true" : "false"));
+    callback(data, buffer);
+
+    sprintf(buffer, "capacity: %d\r\n", s->capacity);
+    callback(data, buffer);
+}
+
+static int goldfish_battery_init(GoldfishDevice *dev)
+{
+    return 0;
+}
+
+DeviceState *goldfish_battery_create(GoldfishBus *gbus)
+{
+    DeviceState *dev;
+    char *name = (char *)"goldfish-battery";
+
+    dev = qdev_create(&gbus->bus, name);
+    qdev_prop_set_string(dev, "name", name);
+    qdev_init_nofail(dev);
+
+    return dev;
+}
+
+static GoldfishDeviceInfo goldfish_battery_info = {
+    .init = goldfish_battery_init,
+    .readfn = goldfish_battery_readfn,
+    .writefn = goldfish_battery_writefn,
+    .qdev.name  = "goldfish-battery",
+    .qdev.size  = sizeof(GoldfishBatteryDevice),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("base", GoldfishDevice, base, 0),
+        DEFINE_PROP_UINT32("id", GoldfishDevice, id, 0),
+        DEFINE_PROP_UINT32("size", GoldfishDevice, size, 0x1000),
+        DEFINE_PROP_UINT32("irq", GoldfishDevice, irq, 0),
+        DEFINE_PROP_UINT32("irq_count", GoldfishDevice, irq_count, 1),
+        DEFINE_PROP_INT32("ac_online", GoldfishBatteryDevice, ac_online,
1),
+        DEFINE_PROP_INT32("status", GoldfishBatteryDevice, status,
POWER_SUPPLY_STATUS_CHARGING),
+        DEFINE_PROP_INT32("health", GoldfishBatteryDevice, health,
POWER_SUPPLY_HEALTH_GOOD),
+        DEFINE_PROP_INT32("present", GoldfishBatteryDevice, present, 1),
 // battery is present
+        DEFINE_PROP_INT32("capacity", GoldfishBatteryDevice, capacity, 50),
// 50% charged
+        DEFINE_PROP_STRING("name", GoldfishDevice, name),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void goldfish_battery_register(void)
+{
+    goldfish_bus_register_withprop(&goldfish_battery_info);
+}
+device_init(goldfish_battery_register);
diff --git a/hw/goldfish_device.h b/hw/goldfish_device.h
index a6e7415..19af64a 100644
--- a/hw/goldfish_device.h
+++ b/hw/goldfish_device.h
@@ -49,12 +49,15 @@ DeviceState *goldfish_tty_create(GoldfishBus *gbus,
CharDriverState *cs, int id,
 DeviceState *goldfish_nand_create(GoldfishBus *gbus);
 DeviceState *goldfish_fb_create(GoldfishBus *gbus, int id);
 DeviceState *goldfish_memlog_create(GoldfishBus *gbus, uint32_t base);
+DeviceState *goldfish_battery_create(GoldfishBus *gbus);

 /* Global functions provided by Goldfish devices */
 void goldfish_bus_register_withprop(GoldfishDeviceInfo *info);
 int goldfish_add_device_no_io(GoldfishDevice *dev);
 void goldfish_device_init(DeviceState *dev, uint32_t base, uint32_t irq);
 void goldfish_device_set_irq(GoldfishDevice *dev, int irq, int level);
+void goldfish_battery_set_prop(void *opaque, int ac, int property, int
value);
+void goldfish_battery_display(void *opaque, void (* callback)(void *data,
const char* string), void *data);

 /** TEMP FILE SUPPORT
  **
diff --git a/hw/power_supply.h b/hw/power_supply.h
new file mode 100644
index 0000000..02733b8
--- /dev/null
+++ b/hw/power_supply.h
@@ -0,0 +1,109 @@
+/*
+ *  Universal power supply monitor class
+ *
+ *  Copyright © 2007  Anton Vorontsov <cbou@mail.ru>
+ *  Copyright © 2004  Szabolcs Gyurko
+ *  Copyright © 2003  Ian Molton <spyro@f2s.com>
+ *
+ *  Modified: 2004, Oct     Szabolcs Gyurko
+ *
+ *  You may use this code as per GPL version 2
+ */
+
+#ifndef __POWER_SUPPLY_H__
+#define __POWER_SUPPLY_H__
+
+/*
+ * All voltages, currents, charges, energies, time and temperatures in uV,
+ * µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise
+ * stated. It's driver's job to convert its raw values to units in which
+ * this class operates.
+ */
+
+/*
+ * For systems where the charger determines the maximum battery capacity
+ * the min and max fields should be used to present these values to user
+ * space. Unused/unknown fields will not appear in sysfs.
+ */
+
+enum {
+ POWER_SUPPLY_STATUS_UNKNOWN = 0,
+ POWER_SUPPLY_STATUS_CHARGING,
+ POWER_SUPPLY_STATUS_DISCHARGING,
+ POWER_SUPPLY_STATUS_NOT_CHARGING,
+ POWER_SUPPLY_STATUS_FULL,
+};
+
+enum {
+ POWER_SUPPLY_HEALTH_UNKNOWN = 0,
+ POWER_SUPPLY_HEALTH_GOOD,
+ POWER_SUPPLY_HEALTH_OVERHEAT,
+ POWER_SUPPLY_HEALTH_DEAD,
+ POWER_SUPPLY_HEALTH_OVERVOLTAGE,
+ POWER_SUPPLY_HEALTH_UNSPEC_FAILURE,
+};
+
+enum {
+ POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0,
+ POWER_SUPPLY_TECHNOLOGY_NiMH,
+ POWER_SUPPLY_TECHNOLOGY_LION,
+ POWER_SUPPLY_TECHNOLOGY_LIPO,
+ POWER_SUPPLY_TECHNOLOGY_LiFe,
+ POWER_SUPPLY_TECHNOLOGY_NiCd,
+};
+
+enum {
+ POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN = 0,
+ POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL,
+ POWER_SUPPLY_CAPACITY_LEVEL_LOW,
+ POWER_SUPPLY_CAPACITY_LEVEL_NORMAL,
+ POWER_SUPPLY_CAPACITY_LEVEL_HIGH,
+ POWER_SUPPLY_CAPACITY_LEVEL_FULL,
+};
+
+enum power_supply_property {
+ /* Properties of type `int' */
+ POWER_SUPPLY_PROP_STATUS = 0,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_VOLTAGE_AVG,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CHARGE_EMPTY,
+ POWER_SUPPLY_PROP_CHARGE_NOW,
+ POWER_SUPPLY_PROP_CHARGE_AVG,
+ POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+ POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
+ POWER_SUPPLY_PROP_ENERGY_FULL,
+ POWER_SUPPLY_PROP_ENERGY_EMPTY,
+ POWER_SUPPLY_PROP_ENERGY_NOW,
+ POWER_SUPPLY_PROP_ENERGY_AVG,
+ POWER_SUPPLY_PROP_CAPACITY, /* in percents! */
+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_TEMP_AMBIENT,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
+ POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
+ /* Properties of type `const char *' */
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+enum power_supply_type {
+ POWER_SUPPLY_TYPE_BATTERY = 0,
+ POWER_SUPPLY_TYPE_UPS,
+ POWER_SUPPLY_TYPE_MAINS,
+ POWER_SUPPLY_TYPE_USB,
+};
+
+#endif /* __POWER_SUPPLY_H__ */
-- 
1.7.4.1

[-- Attachment #2: Type: text/html, Size: 23886 bytes --]

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2011-08-22  9:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-22  9:39 [Qemu-devel] [PATCH 09/11] Goldfish: Added battery device Patrick Jackson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.