*
* This code is licensed under the GNU GPL v2.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
*/
-#include "hw.h"
-#include "devices.h"
+#include "ssi.h"
#include "console.h"
-struct ads7846_state_s {
+typedef struct {
+ SSISlave ssidev;
qemu_irq interrupt;
int input[8];
int cycle;
int output;
-};
+} ADS7846State;
/* Control-byte bitfields */
#define CB_PD0 (1 << 0)
#define ADS_Z1POS(x, y) 600
#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y))
-static void ads7846_int_update(struct ads7846_state_s *s)
+static void ads7846_int_update(ADS7846State *s)
{
if (s->interrupt)
qemu_set_irq(s->interrupt, s->pressure == 0);
}
-uint32_t ads7846_read(void *opaque)
-{
- struct ads7846_state_s *s = (struct ads7846_state_s *) opaque;
-
- return s->output;
-}
-
-void ads7846_write(void *opaque, uint32_t value)
+static uint32_t ads7846_transfer(SSISlave *dev, uint32_t value)
{
- struct ads7846_state_s *s = (struct ads7846_state_s *) opaque;
+ ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
switch (s->cycle ++) {
case 0:
s->cycle = 0;
break;
}
+ return s->output;
}
static void ads7846_ts_event(void *opaque,
int x, int y, int z, int buttons_state)
{
- struct ads7846_state_s *s = opaque;
+ ADS7846State *s = opaque;
if (buttons_state) {
x = 0x7fff - x;
}
}
-static void ads7846_save(QEMUFile *f, void *opaque)
-{
- struct ads7846_state_s *s = (struct ads7846_state_s *) opaque;
- int i;
-
- for (i = 0; i < 8; i ++)
- qemu_put_be32(f, s->input[i]);
- qemu_put_be32(f, s->noise);
- qemu_put_be32(f, s->cycle);
- qemu_put_be32(f, s->output);
-}
-
-static int ads7846_load(QEMUFile *f, void *opaque, int version_id)
+static int ads7856_post_load(void *opaque, int version_id)
{
- struct ads7846_state_s *s = (struct ads7846_state_s *) opaque;
- int i;
-
- for (i = 0; i < 8; i ++)
- s->input[i] = qemu_get_be32(f);
- s->noise = qemu_get_be32(f);
- s->cycle = qemu_get_be32(f);
- s->output = qemu_get_be32(f);
+ ADS7846State *s = opaque;
s->pressure = 0;
ads7846_int_update(s);
-
return 0;
}
-static int ads7846_iid = 0;
+static const VMStateDescription vmstate_ads7846 = {
+ .name = "ads7846",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .post_load = ads7856_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
+ VMSTATE_INT32(noise, ADS7846State),
+ VMSTATE_INT32(cycle, ADS7846State),
+ VMSTATE_INT32(output, ADS7846State),
+ VMSTATE_END_OF_LIST()
+ }
+};
-struct ads7846_state_s *ads7846_init(qemu_irq penirq)
+static int ads7846_init(SSISlave *dev)
{
- struct ads7846_state_s *s;
- s = (struct ads7846_state_s *)
- qemu_mallocz(sizeof(struct ads7846_state_s));
- memset(s, 0, sizeof(struct ads7846_state_s));
+ ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
- s->interrupt = penirq;
+ qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
s->input[0] = ADS_TEMP0; /* TEMP0 */
s->input[2] = ADS_VBAT; /* VBAT */
ads7846_int_update(s);
- register_savevm("ads7846", ads7846_iid ++, 0,
- ads7846_save, ads7846_load, s);
+ vmstate_register(NULL, -1, &vmstate_ads7846, s);
+ return 0;
+}
+
+static void ads7846_class_init(ObjectClass *klass, void *data)
+{
+ SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+ k->init = ads7846_init;
+ k->transfer = ads7846_transfer;
+}
+
+static TypeInfo ads7846_info = {
+ .name = "ads7846",
+ .parent = TYPE_SSI_SLAVE,
+ .instance_size = sizeof(ADS7846State),
+ .class_init = ads7846_class_init,
+};
- return s;
+static void ads7846_register_devices(void)
+{
+ type_register_static(&ads7846_info);
}
+
+device_init(ads7846_register_devices)