#define MP_AUDIO_CLOCK_24MHZ (1 << 9)
#define MP_AUDIO_MONO (1 << 14)
-#ifdef HAS_AUDIO
typedef struct mv88w8618_audio_state {
SysBusDevice busdev;
qemu_irq irq;
uint32_t playback_mode;
uint32_t status;
uint32_t irq_enable;
- unsigned long phys_buf;
+ uint32_t phys_buf;
uint32_t target_buffer;
- unsigned int threshold;
- unsigned int play_pos;
- unsigned int last_free;
+ uint32_t threshold;
+ uint32_t play_pos;
+ uint32_t last_free;
uint32_t clock_div;
DeviceState *wm;
} mv88w8618_audio_state;
int8_t *mem_buffer;
int pos, block_size;
- if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN))
+ if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) {
return;
-
- if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE)
+ }
+ if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) {
free_out <<= 1;
-
- if (!(s->playback_mode & MP_AUDIO_MONO))
+ }
+ if (!(s->playback_mode & MP_AUDIO_MONO)) {
free_out <<= 1;
-
+ }
block_size = s->threshold / 2;
- if (free_out - s->last_free < block_size)
+ if (free_out - s->last_free < block_size) {
return;
-
- if (block_size > 4096)
+ }
+ if (block_size > 4096) {
return;
-
+ }
cpu_physical_memory_read(s->target_buffer + s->play_pos, (void *)buf,
block_size);
mem_buffer = buf;
*codec_buffer++ = *(int16_t *)mem_buffer;
mem_buffer += 2;
}
- } else
+ } else {
memcpy(wm8750_dac_buffer(s->wm, block_size >> 2),
(uint32_t *)mem_buffer, block_size);
+ }
} else {
if (s->playback_mode & MP_AUDIO_MONO) {
codec_buffer = wm8750_dac_buffer(s->wm, block_size);
s->play_pos = 0;
}
- if (s->status & s->irq_enable)
+ if (s->status & s->irq_enable) {
qemu_irq_raise(s->irq);
+ }
}
static void mv88w8618_audio_clock_update(mv88w8618_audio_state *s)
{
int rate;
- if (s->playback_mode & MP_AUDIO_CLOCK_24MHZ)
+ if (s->playback_mode & MP_AUDIO_CLOCK_24MHZ) {
rate = 24576000 / 64; /* 24.576MHz */
- else
+ } else {
rate = 11289600 / 64; /* 11.2896MHz */
-
+ }
rate /= ((s->clock_div >> 8) & 0xff) + 1;
wm8750_set_bclk_in(s->wm, rate);
case MP_AUDIO_IRQ_ENABLE:
s->irq_enable = value;
- if (s->status & s->irq_enable)
+ if (s->status & s->irq_enable) {
qemu_irq_raise(s->irq);
+ }
break;
case MP_AUDIO_TX_START_LO:
}
}
-static void mv88w8618_audio_reset(void *opaque)
+static void mv88w8618_audio_reset(DeviceState *d)
{
- mv88w8618_audio_state *s = opaque;
+ mv88w8618_audio_state *s = FROM_SYSBUS(mv88w8618_audio_state,
+ sysbus_from_qdev(d));
s->playback_mode = 0;
s->status = 0;
s->irq_enable = 0;
+ s->clock_div = 0;
+ s->threshold = 0;
+ s->phys_buf = 0;
}
static CPUReadMemoryFunc * const mv88w8618_audio_readfn[] = {
wm8750_data_req_set(s->wm, mv88w8618_audio_callback, s);
iomemtype = cpu_register_io_memory(mv88w8618_audio_readfn,
- mv88w8618_audio_writefn, s);
+ mv88w8618_audio_writefn, s,
+ DEVICE_NATIVE_ENDIAN);
sysbus_init_mmio(dev, MP_AUDIO_SIZE, iomemtype);
- qemu_register_reset(mv88w8618_audio_reset, s);
-
return 0;
}
+static const VMStateDescription mv88w8618_audio_vmsd = {
+ .name = "mv88w8618_audio",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(playback_mode, mv88w8618_audio_state),
+ VMSTATE_UINT32(status, mv88w8618_audio_state),
+ VMSTATE_UINT32(irq_enable, mv88w8618_audio_state),
+ VMSTATE_UINT32(phys_buf, mv88w8618_audio_state),
+ VMSTATE_UINT32(target_buffer, mv88w8618_audio_state),
+ VMSTATE_UINT32(threshold, mv88w8618_audio_state),
+ VMSTATE_UINT32(play_pos, mv88w8618_audio_state),
+ VMSTATE_UINT32(last_free, mv88w8618_audio_state),
+ VMSTATE_UINT32(clock_div, mv88w8618_audio_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static SysBusDeviceInfo mv88w8618_audio_info = {
.init = mv88w8618_audio_init,
.qdev.name = "mv88w8618_audio",
.qdev.size = sizeof(mv88w8618_audio_state),
+ .qdev.reset = mv88w8618_audio_reset,
+ .qdev.vmsd = &mv88w8618_audio_vmsd,
.qdev.props = (Property[]) {
{
.name = "wm8750",
{/* end of list */}
}
};
-#endif
static void mv88w8618_register_devices(void)
{
-#ifdef HAS_AUDIO
sysbus_register_withprop(&mv88w8618_audio_info);
-#endif
}
device_init(mv88w8618_register_devices)