smc: Make attached avpack configurable

Also improved constant definitions based on https://xboxdevwiki.net/AV_Cables

Co-authored-by: Matt Borgerson <contact@mborgerson.com>
This commit is contained in:
Stanislav Motylkov 2019-09-03 21:30:24 +03:00 committed by mborgerson
parent dd1248a563
commit 5e8af994c0
4 changed files with 83 additions and 4 deletions

View File

@ -29,4 +29,7 @@ void smbus_xbox_smc_init(I2CBus *smbus, int address);
void smbus_cx25871_init(I2CBus *smbus, int address);
void smbus_adm1032_init(I2CBus *smbus, int address);
bool xbox_smc_avpack_to_reg(const char *avpack, uint8_t *value);
void xbox_smc_append_avpack_hint(Error **errp);
#endif

View File

@ -28,6 +28,7 @@
#include "hw/i2c/i2c.h"
#include "hw/i2c/smbus_slave.h"
#include "qemu/config-file.h"
#include "qapi/error.h"
#include "sysemu/sysemu.h"
#include "smbus.h"
@ -55,10 +56,11 @@
#define SMC_REG_AVPACK 0x04
#define SMC_REG_AVPACK_SCART 0x00
#define SMC_REG_AVPACK_HDTV 0x01
#define SMC_REG_AVPACK_VGA_SOG 0x02
#define SMC_REG_AVPACK_VGA 0x02
#define SMC_REG_AVPACK_RFU 0x03
#define SMC_REG_AVPACK_SVIDEO 0x04
#define SMC_REG_AVPACK_COMPOSITE 0x06
#define SMC_REG_AVPACK_VGA 0x07
#define SMC_REG_AVPACK_NONE 0x07
#define SMC_REG_FANMODE 0x05
#define SMC_REG_FANSPEED 0x06
#define SMC_REG_LEDMODE 0x07
@ -86,6 +88,7 @@ typedef struct SMBusSMCDevice {
SMBusDevice smbusdev;
int version_string_index;
uint8_t cmd;
uint8_t avpack_reg;
uint8_t scratch_reg;
} SMBusSMCDevice;
@ -154,8 +157,7 @@ static uint8_t smc_receive_byte(SMBusDevice *dev)
smc->version_string_index++ % (sizeof(smc_version_string) - 1)];
case SMC_REG_AVPACK:
/* pretend to have a composite av pack plugged in */
return SMC_REG_AVPACK_COMPOSITE;
return smc->avpack_reg;
case SMC_REG_SCRATCH:
return smc->scratch_reg;
@ -178,17 +180,62 @@ static uint8_t smc_receive_byte(SMBusDevice *dev)
return 0;
}
bool xbox_smc_avpack_to_reg(const char *avpack, uint8_t *value)
{
uint8_t r;
if (!strcmp(avpack, "composite")) {
r = SMC_REG_AVPACK_COMPOSITE;
} else if (!strcmp(avpack, "scart")) {
r = SMC_REG_AVPACK_SCART;
} else if (!strcmp(avpack, "svideo")) {
r = SMC_REG_AVPACK_SVIDEO;
} else if (!strcmp(avpack, "vga")) {
r = SMC_REG_AVPACK_VGA;
} else if (!strcmp(avpack, "rfu")) {
r = SMC_REG_AVPACK_RFU;
} else if (!strcmp(avpack, "hdtv")) {
r = SMC_REG_AVPACK_HDTV;
} else if (!strcmp(avpack, "none")) {
r = SMC_REG_AVPACK_NONE;
} else {
return false;
}
if (value) {
*value = r;
}
return true;
}
void xbox_smc_append_avpack_hint(Error **errp)
{
error_append_hint(errp, "Valid options are: composite (default), scart, svideo, vga, rfu, hdtv, none\n");
}
static void smbus_smc_realize(DeviceState *dev, Error **errp)
{
SMBusSMCDevice *smc = XBOX_SMC(dev);
char *avpack;
smc->version_string_index = 0;
smc->avpack_reg = 0; /* Default value for Chihiro machine */
smc->scratch_reg = 0;
smc->cmd = 0;
if (object_property_get_bool(qdev_get_machine(), "short-animation", NULL)) {
smc->scratch_reg = SMC_REG_SCRATCH_SHORT_ANIMATION;
}
avpack = object_property_get_str(qdev_get_machine(), "avpack", NULL);
if (avpack) {
if (!xbox_smc_avpack_to_reg(avpack, &smc->avpack_reg)) {
error_setg(errp, "Unsupported avpack option '%s'", avpack);
xbox_smc_append_avpack_hint(errp);
}
g_free(avpack);
}
}
static void smbus_smc_class_initfn(ObjectClass *klass, void *data)

View File

@ -476,6 +476,28 @@ static void machine_set_eeprom(Object *obj, const char *value,
ms->eeprom = g_strdup(value);
}
static char *machine_get_avpack(Object *obj, Error **errp)
{
XboxMachineState *ms = XBOX_MACHINE(obj);
return g_strdup(ms->avpack);
}
static void machine_set_avpack(Object *obj, const char *value,
Error **errp)
{
XboxMachineState *ms = XBOX_MACHINE(obj);
if (!xbox_smc_avpack_to_reg(value, NULL)) {
error_setg(errp, "-machine avpack=%s: unsupported option", value);
xbox_smc_append_avpack_hint(errp);
return;
}
g_free(ms->avpack);
ms->avpack = g_strdup(value);
}
static void machine_set_short_animation(Object *obj, bool value,
Error **errp)
{
@ -502,6 +524,12 @@ static inline void xbox_machine_initfn(Object *obj)
object_property_set_description(obj, "eeprom",
"Xbox EEPROM file", NULL);
object_property_add_str(obj, "avpack", machine_get_avpack,
machine_set_avpack, NULL);
object_property_set_description(obj, "avpack",
"Xbox video connector: composite (default), scart, svideo, vga, rfu, hdtv, none", NULL);
object_property_set_str(obj, "composite", "avpack", NULL);
object_property_add_bool(obj, "short-animation",
machine_get_short_animation,
machine_set_short_animation, NULL);

View File

@ -47,6 +47,7 @@ typedef struct XboxMachineState {
/*< public >*/
char *bootrom;
char *eeprom;
char *avpack;
bool short_animation;
} XboxMachineState;