CS423x: Refactor EEPROM-less mode
This commit is contained in:
@@ -87,11 +87,9 @@ static const uint8_t slam_init_key[32] = { 0x96, 0x35, 0x9A, 0xCD, 0xE6, 0xF3, 0
|
||||
0x5E, 0xAF, 0x57, 0x2B, 0x15, 0x8A, 0xC5, 0xE2,
|
||||
0xF1, 0xF8, 0x7C, 0x3E, 0x9F, 0x4F, 0x27, 0x13,
|
||||
0x09, 0x84, 0x42, 0xA1, 0xD0, 0x68, 0x34, 0x1A };
|
||||
static const uint8_t cs4236b_eeprom[8224] = {
|
||||
static const uint8_t cs4236b_default[] = {
|
||||
// clang-format off
|
||||
/* Chip configuration */
|
||||
0x55, 0xbb, /* magic */
|
||||
0x00, 0x00, /* length */
|
||||
0x00, 0x03, /* CD-ROM and modem decode */
|
||||
0x80, /* misc. config */
|
||||
0x80, /* global config */
|
||||
@@ -102,8 +100,9 @@ static const uint8_t cs4236b_eeprom[8224] = {
|
||||
0x75, 0xb9, 0xfc, /* IRQ routing */
|
||||
0x10, 0x03, /* DMA routing */
|
||||
|
||||
/* PnP resources */
|
||||
0x00
|
||||
/* Default PnP resources */
|
||||
/* TODO: broken, not picked up by VS440FX BIOS, pending hardware research of the actual defaults */
|
||||
0x0e, 0x63, 0x42, 0x36, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x10, 0x00, 0x14, 0x41, 0xd0, 0xff, 0xff, 0x79, 0x00
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -122,6 +121,7 @@ typedef struct cs423x_t {
|
||||
uint16_t ram_addr;
|
||||
uint16_t eeprom_size : 11;
|
||||
uint16_t pnp_offset;
|
||||
uint16_t pnp_size;
|
||||
uint8_t type;
|
||||
uint8_t ad1848_type;
|
||||
uint8_t regs[8];
|
||||
@@ -363,7 +363,8 @@ cs423x_slam_write(UNUSED(uint16_t addr), uint8_t val, void *priv)
|
||||
cs423x_t *dev = (cs423x_t *) priv;
|
||||
uint8_t idx;
|
||||
|
||||
cs423x_log("CS423x: slam_write(%02X)\n", val);
|
||||
if ((dev->slam_state != CRYSTAL_SLAM_NONE) || (val == slam_init_key[dev->key_pos])) /* cut down on ISAPnP-related noise */
|
||||
cs423x_log("CS423x: slam_write(%02X)\n", val);
|
||||
|
||||
switch (dev->slam_state) {
|
||||
case CRYSTAL_SLAM_NONE:
|
||||
@@ -599,7 +600,7 @@ cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig)
|
||||
if (dev->pnp_card) {
|
||||
/* Update PnP resource data if requested. */
|
||||
if (update_rom)
|
||||
isapnp_update_card_rom(dev->pnp_card, &dev->ram_data[dev->pnp_offset], 384);
|
||||
isapnp_update_card_rom(dev->pnp_card, &dev->ram_data[dev->pnp_offset], dev->pnp_size);
|
||||
|
||||
/* Disable PnP key if the PKD bit is set, or if it was disabled by command 0x55. */
|
||||
/* But wait! The TriGem Delhi-III BIOS sends command 0x55, and its behavior doesn't
|
||||
@@ -753,9 +754,21 @@ cs423x_reset(void *priv)
|
||||
/* Clear RAM. */
|
||||
memset(dev->ram_data, 0, sizeof(dev->ram_data));
|
||||
|
||||
/* Load default configuration data to RAM. */
|
||||
memcpy(&dev->ram_data[0x4000], cs4236b_default, sizeof(cs4236b_default));
|
||||
dev->pnp_size = 19;
|
||||
|
||||
if (dev->eeprom) {
|
||||
/* Load EEPROM data to RAM. */
|
||||
memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], MIN(384, ((dev->eeprom_data[2] << 8) | dev->eeprom_data[3]) - 4));
|
||||
/* Load EEPROM data to RAM if the magic bytes are present. */
|
||||
if ((dev->eeprom_data[0] == 0x55) && (dev->eeprom_data[1] == 0xbb)) {
|
||||
cs423x_log("CS423x: EEPROM data valid, loading to RAM\n");
|
||||
dev->pnp_size = (dev->eeprom_data[2] << 8) | dev->eeprom_data[3];
|
||||
if (dev->pnp_size > 384)
|
||||
dev->pnp_size = 384;
|
||||
memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], sizeof(dev->eeprom_data) - 4);
|
||||
} else {
|
||||
cs423x_log("CS423x: EEPROM data invalid, ignoring\n");
|
||||
}
|
||||
|
||||
/* Save EEPROM contents to file. */
|
||||
cs423x_nvram(dev, 1);
|
||||
@@ -800,30 +813,41 @@ cs423x_init(const device_t *info)
|
||||
dev->ad1848_type = (dev->type == CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : AD1848_TYPE_CS4236;
|
||||
dev->pnp_offset = 0x4013;
|
||||
|
||||
/* Different Chip Version and ID registers, which shouldn't be reset by ad1848_init */
|
||||
/* Different Chip Version and ID registers, which shouldn't be reset by ad1848_init. */
|
||||
dev->ad1848.xregs[25] = dev->type;
|
||||
|
||||
if (!(info->local & CRYSTAL_NOEEPROM)) {
|
||||
/* Load EEPROM contents from template. */
|
||||
memcpy(dev->eeprom_data, cs4236b_eeprom, sizeof(cs4236b_eeprom));
|
||||
/* Copy default configuration data. */
|
||||
memcpy(&dev->eeprom_data[4], cs4236b_default, sizeof(cs4236b_default));
|
||||
|
||||
/* Load PnP resource data ROM. */
|
||||
FILE *fp = rom_fopen(PNP_ROM_CS4236B, "rb");
|
||||
if (fp) {
|
||||
(void) !fread(&(dev->eeprom_data[23]), 1, 8201, fp);
|
||||
uint16_t eeprom_pnp_offset = (dev->pnp_offset & 0x1ff) + 4;
|
||||
/* This is wrong. The header field only indicates PnP resource data length, and real chips use
|
||||
it to locate the firmware patch area, but we don't need any of that, so we can get away
|
||||
with pretending the whole ROM is PnP data, at least until we can get full EEPROM dumps. */
|
||||
dev->pnp_size = fread(&dev->eeprom_data[eeprom_pnp_offset], 1, sizeof(dev->eeprom_data) - eeprom_pnp_offset, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* Set content size. */
|
||||
dev->eeprom_data[2] = sizeof(cs4236b_eeprom) >> 8;
|
||||
dev->eeprom_data[3] = sizeof(cs4236b_eeprom) & 0xff;
|
||||
/* Populate EEPROM header if the PnP ROM was loaded. */
|
||||
if (dev->pnp_size) {
|
||||
dev->eeprom_data[0] = 0x55;
|
||||
dev->eeprom_data[1] = 0xbb;
|
||||
dev->eeprom_data[2] = dev->pnp_size >> 8;
|
||||
dev->eeprom_data[3] = dev->pnp_size;
|
||||
}
|
||||
|
||||
/* Set PnP card ID and EEPROM file name. */
|
||||
/* Patch PnP ROM and set EEPROM file name. */
|
||||
switch (dev->type) {
|
||||
case CRYSTAL_CS4235:
|
||||
dev->eeprom_data[8] = 0x05;
|
||||
dev->eeprom_data[16] = 0x08;
|
||||
dev->eeprom_data[26] = 0x25;
|
||||
dev->eeprom_data[44] = '5';
|
||||
if (dev->pnp_size) {
|
||||
dev->eeprom_data[8] = 0x05;
|
||||
dev->eeprom_data[16] = 0x08;
|
||||
dev->eeprom_data[26] = 0x25;
|
||||
dev->eeprom_data[44] = '5';
|
||||
}
|
||||
dev->nvr_path = "cs4235.nvr";
|
||||
break;
|
||||
|
||||
@@ -832,14 +856,18 @@ cs423x_init(const device_t *info)
|
||||
break;
|
||||
|
||||
case CRYSTAL_CS4237B:
|
||||
dev->eeprom_data[26] = 0x37;
|
||||
dev->eeprom_data[44] = '7';
|
||||
if (dev->pnp_size) {
|
||||
dev->eeprom_data[26] = 0x37;
|
||||
dev->eeprom_data[44] = '7';
|
||||
}
|
||||
dev->nvr_path = "cs4237b.nvr";
|
||||
break;
|
||||
|
||||
case CRYSTAL_CS4238B:
|
||||
dev->eeprom_data[26] = 0x38;
|
||||
dev->eeprom_data[44] = '8';
|
||||
if (dev->pnp_size) {
|
||||
dev->eeprom_data[26] = 0x38;
|
||||
dev->eeprom_data[44] = '8';
|
||||
}
|
||||
dev->nvr_path = "cs4238b.nvr";
|
||||
break;
|
||||
|
||||
@@ -864,8 +892,8 @@ cs423x_init(const device_t *info)
|
||||
/* Initialize I2C bus for the EEPROM. */
|
||||
dev->i2c = i2c_gpio_init("nvr_cs423x");
|
||||
|
||||
/* Initialize I2C EEPROM if the contents are valid. */
|
||||
if ((dev->eeprom_data[0] == 0x55) && (dev->eeprom_data[1] == 0xbb))
|
||||
/* Initialize I2C EEPROM if enabled. */
|
||||
if (!(info->local & CRYSTAL_NOEEPROM))
|
||||
dev->eeprom = i2c_eeprom_init(i2c_gpio_get_bus(dev->i2c), 0x50, dev->eeprom_data, sizeof(dev->eeprom_data), 1);
|
||||
|
||||
/* Initialize ISAPnP. */
|
||||
|
||||
Reference in New Issue
Block a user