pcspk: Convert to qdev

Convert the PC speaker device to a qdev ISA model. Move the public
interface to a dedicated header file at this chance.

CC: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Jan Kiszka 2012-02-17 11:24:34 +01:00 committed by Anthony Liguori
parent ce967e2f33
commit 302fe51b59
7 changed files with 110 additions and 18 deletions

View file

@ -28,6 +28,7 @@
#include "audio/audio.h"
#include "qemu-timer.h"
#include "i8254.h"
#include "pcspk.h"
#define PCSPK_BUF_LEN 1792
#define PCSPK_SAMPLE_RATE 32000
@ -35,10 +36,13 @@
#define PCSPK_MIN_COUNT ((PIT_FREQ + PCSPK_MAX_FREQ - 1) / PCSPK_MAX_FREQ)
typedef struct {
ISADevice dev;
MemoryRegion ioport;
uint32_t iobase;
uint8_t sample_buf[PCSPK_BUF_LEN];
QEMUSoundCard card;
SWVoiceOut *voice;
ISADevice *pit;
void *pit;
unsigned int pit_count;
unsigned int samples;
unsigned int play_pos;
@ -47,7 +51,7 @@ typedef struct {
} PCSpkState;
static const char *s_spk = "pcspk";
static PCSpkState pcspk_state;
static PCSpkState *pcspk_state;
static inline void generate_samples(PCSpkState *s)
{
@ -99,7 +103,7 @@ static void pcspk_callback(void *opaque, int free)
int pcspk_audio_init(ISABus *bus)
{
PCSpkState *s = &pcspk_state;
PCSpkState *s = pcspk_state;
struct audsettings as = {PCSPK_SAMPLE_RATE, 1, AUD_FMT_U8, 0};
AUD_register_card(s_spk, &s->card);
@ -113,7 +117,8 @@ int pcspk_audio_init(ISABus *bus)
return 0;
}
static uint32_t pcspk_ioport_read(void *opaque, uint32_t addr)
static uint64_t pcspk_io_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{
PCSpkState *s = opaque;
int out;
@ -124,7 +129,8 @@ static uint32_t pcspk_ioport_read(void *opaque, uint32_t addr)
return pit_get_gate(s->pit, 2) | (s->data_on << 1) | s->dummy_refresh_clock | out;
}
static void pcspk_ioport_write(void *opaque, uint32_t addr, uint32_t val)
static void pcspk_io_write(void *opaque, target_phys_addr_t addr, uint64_t val,
unsigned size)
{
PCSpkState *s = opaque;
const int gate = val & 1;
@ -138,11 +144,52 @@ static void pcspk_ioport_write(void *opaque, uint32_t addr, uint32_t val)
}
}
void pcspk_init(ISADevice *pit)
{
PCSpkState *s = &pcspk_state;
static const MemoryRegionOps pcspk_io_ops = {
.read = pcspk_io_read,
.write = pcspk_io_write,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
};
s->pit = pit;
register_ioport_read(0x61, 1, 1, pcspk_ioport_read, s);
register_ioport_write(0x61, 1, 1, pcspk_ioport_write, s);
static int pcspk_initfn(ISADevice *dev)
{
PCSpkState *s = DO_UPCAST(PCSpkState, dev, dev);
memory_region_init_io(&s->ioport, &pcspk_io_ops, s, "elcr", 1);
isa_register_ioport(dev, &s->ioport, s->iobase);
pcspk_state = s;
return 0;
}
static Property pcspk_properties[] = {
DEFINE_PROP_HEX32("iobase", PCSpkState, iobase, -1),
DEFINE_PROP_PTR("pit", PCSpkState, pit),
DEFINE_PROP_END_OF_LIST(),
};
static void pcspk_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
ic->init = pcspk_initfn;
dc->no_user = 1;
dc->props = pcspk_properties;
}
static TypeInfo pcspk_info = {
.name = "isa-pcspk",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(PCSpkState),
.class_init = pcspk_class_initfn,
};
static void pcspk_register(void)
{
type_register_static(&pcspk_info);
}
type_init(pcspk_register)