]> git.proxmox.com Git - qemu.git/blobdiff - hw/wm8750.c
lm32: system control model
[qemu.git] / hw / wm8750.c
index 7086a79988075c140d5d5497db6a10aa1c68243d..c9c674451b4c5664ffa037237d2ebd8f154cea3b 100644 (file)
@@ -46,6 +46,7 @@ typedef struct {
     uint8_t diff[2], pol, ds, monomix[2], alc, mute;
     uint8_t path[4], mpath[2], power, format;
     const WMRate *rate;
+    uint8_t rate_vmstate;
     int adc_hz, dac_hz, ext_adc_hz, ext_dac_hz, master;
 } WM8750State;
 
@@ -61,12 +62,11 @@ static const uint8_t wm8750_vol_db_table[] = {
 
 static inline void wm8750_in_load(WM8750State *s)
 {
-    int acquired;
     if (s->idx_in + s->req_in <= sizeof(s->data_in))
         return;
     s->idx_in = audio_MAX(0, (int) sizeof(s->data_in) - s->req_in);
-    acquired = AUD_read(*s->in[0], s->data_in + s->idx_in,
-                    sizeof(s->data_in) - s->idx_in);
+    AUD_read(*s->in[0], s->data_in + s->idx_in,
+             sizeof(s->data_in) - s->idx_in);
 }
 
 static inline void wm8750_out_flush(WM8750State *s)
@@ -171,7 +171,6 @@ static void wm8750_set_format(WM8750State *s)
     int i;
     struct audsettings in_fmt;
     struct audsettings out_fmt;
-    struct audsettings monoout_fmt;
 
     wm8750_out_flush(s);
 
@@ -212,10 +211,6 @@ static void wm8750_set_format(WM8750State *s)
     out_fmt.nchannels = 2;
     out_fmt.freq = s->dac_hz;
     out_fmt.fmt = AUD_FMT_S16;
-    monoout_fmt.endianness = 0;
-    monoout_fmt.nchannels = 1;
-    monoout_fmt.freq = s->rate->dac_hz;
-    monoout_fmt.fmt = AUD_FMT_S16;
 
     s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
                     CODEC ".speaker", s, wm8750_audio_out_cb, &out_fmt);
@@ -259,7 +254,7 @@ static void wm8750_clk_update(WM8750State *s, int ext)
     }
 }
 
-void wm8750_reset(i2c_slave *i2c)
+static void wm8750_reset(i2c_slave *i2c)
 {
     WM8750State *s = (WM8750State *) i2c;
     s->rate = &wm_rate_table[0];
@@ -564,101 +559,64 @@ static int wm8750_rx(i2c_slave *i2c)
     return 0x00;
 }
 
-static void wm8750_save(QEMUFile *f, void *opaque)
+static void wm8750_pre_save(void *opaque)
 {
-    WM8750State *s = (WM8750State *) opaque;
-    int i;
-    qemu_put_8s(f, &s->i2c_data[0]);
-    qemu_put_8s(f, &s->i2c_data[1]);
-    qemu_put_be32(f, s->i2c_len);
-    qemu_put_be32(f, s->enable);
-    qemu_put_be32(f, s->idx_in);
-    qemu_put_be32(f, s->req_in);
-    qemu_put_be32(f, s->idx_out);
-    qemu_put_be32(f, s->req_out);
-
-    for (i = 0; i < 7; i ++)
-        qemu_put_8s(f, &s->outvol[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_put_8s(f, &s->outmute[i]);
-    for (i = 0; i < 4; i ++)
-        qemu_put_8s(f, &s->invol[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_put_8s(f, &s->inmute[i]);
-
-    for (i = 0; i < 2; i ++)
-        qemu_put_8s(f, &s->diff[i]);
-    qemu_put_8s(f, &s->pol);
-    qemu_put_8s(f, &s->ds);
-    for (i = 0; i < 2; i ++)
-        qemu_put_8s(f, &s->monomix[i]);
-    qemu_put_8s(f, &s->alc);
-    qemu_put_8s(f, &s->mute);
-    for (i = 0; i < 4; i ++)
-        qemu_put_8s(f, &s->path[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_put_8s(f, &s->mpath[i]);
-    qemu_put_8s(f, &s->format);
-    qemu_put_8s(f, &s->power);
-    qemu_put_byte(f, (s->rate - wm_rate_table) / sizeof(*s->rate));
-    i2c_slave_save(f, &s->i2c);
+    WM8750State *s = opaque;
+
+    s->rate_vmstate = (s->rate - wm_rate_table) / sizeof(*s->rate);
 }
 
-static int wm8750_load(QEMUFile *f, void *opaque, int version_id)
+static int wm8750_post_load(void *opaque, int version_id)
 {
-    WM8750State *s = (WM8750State *) opaque;
-    int i;
-    qemu_get_8s(f, &s->i2c_data[0]);
-    qemu_get_8s(f, &s->i2c_data[1]);
-    s->i2c_len = qemu_get_be32(f);
-    s->enable = qemu_get_be32(f);
-    s->idx_in = qemu_get_be32(f);
-    s->req_in = qemu_get_be32(f);
-    s->idx_out = qemu_get_be32(f);
-    s->req_out = qemu_get_be32(f);
-
-    for (i = 0; i < 7; i ++)
-        qemu_get_8s(f, &s->outvol[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_get_8s(f, &s->outmute[i]);
-    for (i = 0; i < 4; i ++)
-        qemu_get_8s(f, &s->invol[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_get_8s(f, &s->inmute[i]);
-
-    for (i = 0; i < 2; i ++)
-        qemu_get_8s(f, &s->diff[i]);
-    qemu_get_8s(f, &s->pol);
-    qemu_get_8s(f, &s->ds);
-    for (i = 0; i < 2; i ++)
-        qemu_get_8s(f, &s->monomix[i]);
-    qemu_get_8s(f, &s->alc);
-    qemu_get_8s(f, &s->mute);
-    for (i = 0; i < 4; i ++)
-        qemu_get_8s(f, &s->path[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_get_8s(f, &s->mpath[i]);
-    qemu_get_8s(f, &s->format);
-    qemu_get_8s(f, &s->power);
-    s->rate = &wm_rate_table[(uint8_t) qemu_get_byte(f) & 0x1f];
-    i2c_slave_load(f, &s->i2c);
+    WM8750State *s = opaque;
+
+    s->rate = &wm_rate_table[s->rate_vmstate & 0x1f];
     return 0;
 }
 
-i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio)
+static const VMStateDescription vmstate_wm8750 = {
+    .name = CODEC,
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .pre_save = wm8750_pre_save,
+    .post_load = wm8750_post_load,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT8_ARRAY(i2c_data, WM8750State, 2),
+        VMSTATE_INT32(i2c_len, WM8750State),
+        VMSTATE_INT32(enable, WM8750State),
+        VMSTATE_INT32(idx_in, WM8750State),
+        VMSTATE_INT32(req_in, WM8750State),
+        VMSTATE_INT32(idx_out, WM8750State),
+        VMSTATE_INT32(req_out, WM8750State),
+        VMSTATE_UINT8_ARRAY(outvol, WM8750State, 7),
+        VMSTATE_UINT8_ARRAY(outmute, WM8750State, 2),
+        VMSTATE_UINT8_ARRAY(invol, WM8750State, 4),
+        VMSTATE_UINT8_ARRAY(inmute, WM8750State, 2),
+        VMSTATE_UINT8_ARRAY(diff, WM8750State, 2),
+        VMSTATE_UINT8(pol, WM8750State),
+        VMSTATE_UINT8(ds, WM8750State),
+        VMSTATE_UINT8_ARRAY(monomix, WM8750State, 2),
+        VMSTATE_UINT8(alc, WM8750State),
+        VMSTATE_UINT8(mute, WM8750State),
+        VMSTATE_UINT8_ARRAY(path, WM8750State, 4),
+        VMSTATE_UINT8_ARRAY(mpath, WM8750State, 2),
+        VMSTATE_UINT8(format, WM8750State),
+        VMSTATE_UINT8(power, WM8750State),
+        VMSTATE_UINT8(rate_vmstate, WM8750State),
+        VMSTATE_I2C_SLAVE(i2c, WM8750State),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static int wm8750_init(i2c_slave *i2c)
 {
-    WM8750State *s = (WM8750State *)
-            i2c_slave_init(bus, 0, sizeof(WM8750State));
-    s->i2c.event = wm8750_event;
-    s->i2c.recv = wm8750_rx;
-    s->i2c.send = wm8750_tx;
+    WM8750State *s = FROM_I2C_SLAVE(WM8750State, i2c);
 
-    AUD_register_card(audio, CODEC, &s->card);
+    AUD_register_card(CODEC, &s->card);
     wm8750_reset(&s->i2c);
 
-    register_savevm(CODEC, -1, 0, wm8750_save, wm8750_load, s);
-
-    return &s->i2c;
+    return 0;
 }
 
 #if 0
@@ -671,10 +629,10 @@ static void wm8750_fini(i2c_slave *i2c)
 }
 #endif
 
-void wm8750_data_req_set(i2c_slave *i2c,
+void wm8750_data_req_set(DeviceState *dev,
                 void (*data_req)(void *, int, int), void *opaque)
 {
-    WM8750State *s = (WM8750State *) i2c;
+    WM8750State *s = FROM_I2C_SLAVE(WM8750State, I2C_SLAVE_FROM_QDEV(dev));
     s->data_req = data_req;
     s->opaque = opaque;
 }
@@ -730,3 +688,20 @@ void wm8750_set_bclk_in(void *opaque, int new_hz)
     s->ext_dac_hz = new_hz;
     wm8750_clk_update(s, 1);
 }
+
+static I2CSlaveInfo wm8750_info = {
+    .qdev.name = "wm8750",
+    .qdev.size = sizeof(WM8750State),
+    .qdev.vmsd = &vmstate_wm8750,
+    .init = wm8750_init,
+    .event = wm8750_event,
+    .recv = wm8750_rx,
+    .send = wm8750_tx
+};
+
+static void wm8750_register_devices(void)
+{
+    i2c_register_slave(&wm8750_info);
+}
+
+device_init(wm8750_register_devices)