mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
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:
parent
ce967e2f33
commit
302fe51b59
7 changed files with 110 additions and 18 deletions
69
hw/pcspk.c
69
hw/pcspk.c
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue