* Copyright (c) 2006-2007 CodeSourcery.
* Written by Paul Brook
*
- * This code is licenced under the GPL.
+ * This code is licensed under the GPL.
*/
/* The controller can support a variety of different displays, but we only
implement one. Most of the commends relating to brightness and geometry
setup are ignored. */
-#include "hw.h"
#include "i2c.h"
#include "console.h"
//#define DEBUG_SSD0303 1
#ifdef DEBUG_SSD0303
-#define DPRINTF(fmt, args...) \
-do { printf("ssd0303: " fmt , ##args); } while (0)
-#define BADF(fmt, args...) \
-do { fprintf(stderr, "ssd0303: error: " fmt , ##args); exit(1);} while (0)
+#define DPRINTF(fmt, ...) \
+do { printf("ssd0303: " fmt , ## __VA_ARGS__); } while (0)
+#define BADF(fmt, ...) \
+do { fprintf(stderr, "ssd0303: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#define BADF(fmt, args...) \
-do { fprintf(stderr, "ssd0303: error: " fmt , ##args);} while (0)
+#define DPRINTF(fmt, ...) do {} while(0)
+#define BADF(fmt, ...) \
+do { fprintf(stderr, "ssd0303: error: " fmt , ## __VA_ARGS__);} while (0)
#endif
/* Scaling factor for pixels. */
};
typedef struct {
- i2c_slave i2c;
+ I2CSlave i2c;
DisplayState *ds;
int row;
int col;
uint8_t framebuffer[132*8];
} ssd0303_state;
-static int ssd0303_recv(i2c_slave *i2c)
+static int ssd0303_recv(I2CSlave *i2c)
{
BADF("Reads not implemented\n");
return -1;
}
-static int ssd0303_send(i2c_slave *i2c, uint8_t data)
+static int ssd0303_send(I2CSlave *i2c, uint8_t data)
{
ssd0303_state *s = (ssd0303_state *)i2c;
enum ssd0303_cmd old_cmd_state;
DPRINTF("cmd 0x%02x\n", data);
s->mode = SSD0303_IDLE;
switch (data) {
- case 0x00 ... 0x0f: /* Set lower colum address. */
+ case 0x00 ... 0x0f: /* Set lower column address. */
s->col = (s->col & 0xf0) | (data & 0xf);
break;
case 0x10 ... 0x20: /* Set higher column address. */
case 0xa7: /* Inverse on. */
s->inverse = 1;
break;
- case 0xa8: /* Set multipled ratio (Ignored). */
+ case 0xa8: /* Set multiplied ratio (Ignored). */
s->cmd_state = SSD0303_CMD_SKIP1;
break;
case 0xad: /* DC-DC power control. */
return 0;
}
-static void ssd0303_event(i2c_slave *i2c, enum i2c_event event)
+static void ssd0303_event(I2CSlave *i2c, enum i2c_event event)
{
ssd0303_state *s = (ssd0303_state *)i2c;
switch (event) {
s->redraw = 1;
}
-static void ssd0303_save(QEMUFile *f, void *opaque)
-{
- ssd0303_state *s = (ssd0303_state *)opaque;
+static const VMStateDescription vmstate_ssd0303 = {
+ .name = "ssd0303_oled",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_INT32(row, ssd0303_state),
+ VMSTATE_INT32(col, ssd0303_state),
+ VMSTATE_INT32(start_line, ssd0303_state),
+ VMSTATE_INT32(mirror, ssd0303_state),
+ VMSTATE_INT32(flash, ssd0303_state),
+ VMSTATE_INT32(enabled, ssd0303_state),
+ VMSTATE_INT32(inverse, ssd0303_state),
+ VMSTATE_INT32(redraw, ssd0303_state),
+ VMSTATE_UINT32(mode, ssd0303_state),
+ VMSTATE_UINT32(cmd_state, ssd0303_state),
+ VMSTATE_BUFFER(framebuffer, ssd0303_state),
+ VMSTATE_I2C_SLAVE(i2c, ssd0303_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
- qemu_put_be32(f, s->row);
- qemu_put_be32(f, s->col);
- qemu_put_be32(f, s->start_line);
- qemu_put_be32(f, s->mirror);
- qemu_put_be32(f, s->flash);
- qemu_put_be32(f, s->enabled);
- qemu_put_be32(f, s->inverse);
- qemu_put_be32(f, s->redraw);
- qemu_put_be32(f, s->mode);
- qemu_put_be32(f, s->cmd_state);
- qemu_put_buffer(f, s->framebuffer, sizeof(s->framebuffer));
+static int ssd0303_init(I2CSlave *i2c)
+{
+ ssd0303_state *s = FROM_I2C_SLAVE(ssd0303_state, i2c);
- i2c_slave_save(f, &s->i2c);
+ s->ds = graphic_console_init(ssd0303_update_display,
+ ssd0303_invalidate_display,
+ NULL, NULL, s);
+ qemu_console_resize(s->ds, 96 * MAGNIFY, 16 * MAGNIFY);
+ return 0;
}
-static int ssd0303_load(QEMUFile *f, void *opaque, int version_id)
+static void ssd0303_class_init(ObjectClass *klass, void *data)
{
- ssd0303_state *s = (ssd0303_state *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
- s->row = qemu_get_be32(f);
- s->col = qemu_get_be32(f);
- s->start_line = qemu_get_be32(f);
- s->mirror = qemu_get_be32(f);
- s->flash = qemu_get_be32(f);
- s->enabled = qemu_get_be32(f);
- s->inverse = qemu_get_be32(f);
- s->redraw = qemu_get_be32(f);
- s->mode = qemu_get_be32(f);
- s->cmd_state = qemu_get_be32(f);
- qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));
-
- i2c_slave_load(f, &s->i2c);
-
- return 0;
+ k->init = ssd0303_init;
+ k->event = ssd0303_event;
+ k->recv = ssd0303_recv;
+ k->send = ssd0303_send;
+ dc->vmsd = &vmstate_ssd0303;
}
-void ssd0303_init(i2c_bus *bus, int address)
-{
- ssd0303_state *s;
+static TypeInfo ssd0303_info = {
+ .name = "ssd0303",
+ .parent = TYPE_I2C_SLAVE,
+ .instance_size = sizeof(ssd0303_state),
+ .class_init = ssd0303_class_init,
+};
- s = (ssd0303_state *)i2c_slave_init(bus, address, sizeof(ssd0303_state));
- s->i2c.event = ssd0303_event;
- s->i2c.recv = ssd0303_recv;
- s->i2c.send = ssd0303_send;
- s->ds = graphic_console_init(ssd0303_update_display,
- ssd0303_invalidate_display,
- NULL, NULL, s);
- qemu_console_resize(s->ds, 96 * MAGNIFY, 16 * MAGNIFY);
- register_savevm("ssd0303_oled", -1, 1, ssd0303_save, ssd0303_load, s);
+static void ssd0303_register_types(void)
+{
+ type_register_static(&ssd0303_info);
}
+
+type_init(ssd0303_register_types)