vid_mga: Implement DDC on the Millennium
This commit is contained in:
@@ -398,6 +398,7 @@ extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, sv
|
||||
extern void tvp3026_recalctimings(void *priv, svga_t *svga);
|
||||
extern void tvp3026_hwcursor_draw(svga_t *svga, int displine);
|
||||
extern float tvp3026_getclock(int clock, void *priv);
|
||||
extern void tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), void (*write)(uint8_t cntl, uint8_t data, void *priv), void *cb_priv, void *priv);
|
||||
|
||||
# ifdef EMU_DEVICE_H
|
||||
extern const device_t ati68860_ramdac_device;
|
||||
|
@@ -5314,6 +5314,27 @@ mystique_hwcursor_draw(svga_t *svga, int displine)
|
||||
svga->hwcursor_latch.addr += 16;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
mystique_tvp3026_gpio_read(uint8_t cntl, void *priv)
|
||||
{
|
||||
mystique_t *mystique = (mystique_t *) priv;
|
||||
|
||||
uint8_t ret = 0xff;
|
||||
if (!i2c_gpio_get_scl(mystique->i2c_ddc))
|
||||
ret &= ~0x10;
|
||||
if (!i2c_gpio_get_sda(mystique->i2c_ddc))
|
||||
ret &= ~0x04;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mystique_tvp3026_gpio_write(uint8_t cntl, uint8_t data, void *priv)
|
||||
{
|
||||
mystique_t *mystique = (mystique_t *) priv;
|
||||
|
||||
i2c_gpio_set(mystique->i2c_ddc, !(cntl & 0x10) || (data & 0x10), !(cntl & 0x04) || (data & 0x04));
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
mystique_pci_read(UNUSED(int func), int addr, void *priv)
|
||||
{
|
||||
@@ -5625,6 +5646,7 @@ mystique_init(const device_t *info)
|
||||
mystique->svga.ramdac = device_add(&tvp3026_ramdac_device);
|
||||
mystique->svga.clock_gen = mystique->svga.ramdac;
|
||||
mystique->svga.getclock = tvp3026_getclock;
|
||||
tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac);
|
||||
} else {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique);
|
||||
svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20,
|
||||
|
@@ -55,6 +55,11 @@ typedef struct tvp3026_ramdac_t {
|
||||
uint8_t n;
|
||||
uint8_t p;
|
||||
} pix, mem, loop;
|
||||
uint8_t gpio_cntl;
|
||||
uint8_t gpio_data;
|
||||
uint8_t (*gpio_read)(uint8_t cntl, void *priv);
|
||||
void (*gpio_write)(uint8_t cntl, uint8_t val, void *priv);
|
||||
void *gpio_priv;
|
||||
} tvp3026_ramdac_t;
|
||||
|
||||
static void
|
||||
@@ -211,6 +216,16 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svg
|
||||
ramdac->misc = val;
|
||||
svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT;
|
||||
break;
|
||||
case 0x2a: /* General-Purpose I/O Control */
|
||||
ramdac->gpio_cntl = val;
|
||||
if (ramdac->gpio_write)
|
||||
ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv);
|
||||
break;
|
||||
case 0x2b: /* General-Purpose I/O Data */
|
||||
ramdac->gpio_data = val;
|
||||
if (ramdac->gpio_write)
|
||||
ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv);
|
||||
break;
|
||||
case 0x2c: /* PLL Address */
|
||||
ramdac->pll_addr = val;
|
||||
break;
|
||||
@@ -389,6 +404,16 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga)
|
||||
case 0x1e: /* Miscellaneous Control */
|
||||
temp = ramdac->misc;
|
||||
break;
|
||||
case 0x2a: /* General-Purpose I/O Control */
|
||||
temp = ramdac->gpio_cntl;
|
||||
break;
|
||||
case 0x2b: /* General-Purpose I/O Data */
|
||||
if (ramdac->gpio_read) {
|
||||
temp = 0xe0 | (ramdac->gpio_cntl & 0x1f); /* keep upper bits untouched */
|
||||
ramdac->gpio_data = (ramdac->gpio_data & temp) | (ramdac->gpio_read(ramdac->gpio_cntl, ramdac->gpio_priv) & ~temp);
|
||||
}
|
||||
temp = ramdac->gpio_data;
|
||||
break;
|
||||
case 0x2c: /* PLL Address */
|
||||
temp = ramdac->pll_addr;
|
||||
break;
|
||||
@@ -630,6 +655,18 @@ tvp3026_getclock(int clock, void *priv)
|
||||
return f_pll;
|
||||
}
|
||||
|
||||
void
|
||||
tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv),
|
||||
void (*write)(uint8_t cntl, uint8_t val, void *priv),
|
||||
void *cb_priv, void *priv)
|
||||
{
|
||||
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv;
|
||||
|
||||
ramdac->gpio_read = read;
|
||||
ramdac->gpio_write = write;
|
||||
ramdac->gpio_priv = cb_priv;
|
||||
}
|
||||
|
||||
void *
|
||||
tvp3026_ramdac_init(const device_t *info)
|
||||
{
|
||||
|
Reference in New Issue
Block a user