LCD + Multitouch working!!

This commit is contained in:
Martijn de Vos committed 2023-12-31 14:45:21 +01:00
1 parent 51aeda9707
commit 287b4f33ba
7 files changed
+63 -16

No files matched your search

+13 -4
View File
@@ -194,10 +194,16 @@ static void ipod_touch_machine_init(MachineState *machine)
IPodTouchSYSICState *sysic_state = IPOD_TOUCH_SYSIC(dev);
nms->sysic = (IPodTouchSYSICState *) g_malloc0(sizeof(struct IPodTouchSYSICState));
memory_region_add_subregion(sysmem, SYSIC_MEM_BASE, &sysic_state->iomem);
// busdev = SYS_BUS_DEVICE(dev);
// for(int grp = 0; grp < GPIO_NUMINTGROUPS; grp++) {
// sysbus_connect_irq(busdev, grp, s5l8900_get_irq(nms, S5L8900_GPIO_IRQS[grp]));
// }
busdev = SYS_BUS_DEVICE(dev);
for(int grp = 0; grp < GPIO_NUMINTGROUPS; grp++) {
sysbus_connect_irq(busdev, grp, s5l8900_get_irq(nms, S5L8900_GPIO_IRQS[grp]));
}
sysbus_connect_irq(busdev, 0, s5l8900_get_irq(nms, S5L8900_GPIO_G0_IRQ));
sysbus_connect_irq(busdev, 0, s5l8900_get_irq(nms, S5L8900_GPIO_G1_IRQ));
sysbus_connect_irq(busdev, 0, s5l8900_get_irq(nms, S5L8900_GPIO_G2_IRQ));
sysbus_connect_irq(busdev, 0, s5l8900_get_irq(nms, S5L8900_GPIO_G3_IRQ));
sysbus_connect_irq(busdev, 0, s5l8900_get_irq(nms, S5L8900_GPIO_G4_IRQ));
// init GPIO
dev = qdev_new("ipodtouch.gpio");
@@ -266,6 +272,8 @@ static void ipod_touch_machine_init(MachineState *machine)
set_spi_base(4);
dev = sysbus_create_simple("ipodtouch.spi", SPI4_MEM_BASE, s5l8900_get_irq(nms, S5L8720_SPI4_IRQ));
IPodTouchSPIState *spi4_state = IPOD_TOUCH_SPI(dev);
spi4_state->mt->sysic = sysic_state;
spi4_state->mt->gpio_state = gpio_state;
nms->spi4_state = spi4_state;
// init the chip ID module
@@ -370,6 +378,7 @@ static void ipod_touch_machine_init(MachineState *machine)
dev = qdev_new("ipodtouch.lcd");
IPodTouchLCDState *lcd_state = IPOD_TOUCH_LCD(dev);
lcd_state->sysmem = sysmem;
lcd_state->mt = spi4_state->mt;
nms->lcd_state = lcd_state;
busdev = SYS_BUS_DEVICE(dev);
memory_region_add_subregion(sysmem, DISPLAY_MEM_BASE, &lcd_state->iomem);
+1 -1
View File
@@ -93,7 +93,7 @@ static void read_nand_pages(IPodTouchFMSSState *s)
static uint64_t ipod_touch_fmss_read(void *opaque, hwaddr addr, unsigned size)
{
fprintf(stderr, "%s: read from location 0x%08x\n", __func__, addr);
//fprintf(stderr, "%s: read from location 0x%08x\n", __func__, addr);
IPodTouchFMSSState *s = (IPodTouchFMSSState *)opaque;
switch(addr)
+33 -8
View File
@@ -5,7 +5,7 @@
static uint64_t ipod_touch_lcd_read(void *opaque, hwaddr addr, unsigned size)
{
fprintf(stderr, "%s: read from location 0x%08x\n", __func__, addr);
//printf("%s: read from location 0x%08x\n", __func__, addr);
IPodTouchLCDState *s = (IPodTouchLCDState *)opaque;
switch(addr)
@@ -14,6 +14,8 @@ static uint64_t ipod_touch_lcd_read(void *opaque, hwaddr addr, unsigned size)
return 2;
case 0x4:
return s->lcd_con;
case 0xC:
return 0x1; //s->unknown1;
case 0x20:
return s->w1_display_depth_info;
case 0x24:
@@ -34,12 +36,16 @@ static uint64_t ipod_touch_lcd_read(void *opaque, hwaddr addr, unsigned size)
static void ipod_touch_lcd_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
IPodTouchLCDState *s = (IPodTouchLCDState *)opaque;
fprintf(stderr, "%s: writing 0x%08x to 0x%08x\n", __func__, val, addr);
//printf("%s: writing 0x%08x to 0x%08x\n", __func__, val, addr);
switch(addr) {
case 0x4:
s->lcd_con = val;
break;
case 0xC:
s->unknown1 = val;
qemu_irq_lower(s->irq);
break;
case 0x20:
s->w1_display_depth_info = val;
break;
@@ -52,9 +58,6 @@ static void ipod_touch_lcd_write(void *opaque, hwaddr addr, uint64_t val, unsign
case 0x30:
s->w1_display_resolution_info = val;
break;
case 0xC:
qemu_irq_lower(s->irq);
break;
}
}
@@ -136,13 +139,35 @@ static const GraphicHwOps gfx_ops = {
.gfx_update = lcd_refresh,
};
static void ipod_touch_lcd_mouse_event(void *opaque, int x, int y, int z, int buttons_state)
{
//printf("CLICKY %d %d %d %d\n", x, y, z, buttons_state);
// convert x and y to fractional numbers
float fx = x / pow(2, 15);
float fy = 1 - y / pow(2, 15);
IPodTouchLCDState *lcd = (IPodTouchLCDState *) opaque;
lcd->mt->prev_touch_x = lcd->mt->touch_x;
lcd->mt->prev_touch_y = lcd->mt->touch_y;
lcd->mt->touch_x = fx;
lcd->mt->touch_y = fy;
if(buttons_state && !lcd->mt->touch_down) {
ipod_touch_multitouch_on_touch(lcd->mt);
}
else if(!buttons_state && lcd->mt->touch_down) {
ipod_touch_multitouch_on_release(lcd->mt);
}
}
static void refresh_timer_tick(void *opaque)
{
IPodTouchLCDState *s = (IPodTouchLCDState *)opaque;
//qemu_irq_raise(s->irq);
qemu_irq_raise(s->irq);
//timer_mod(s->refresh_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + NANOSECONDS_PER_SECOND / LCD_REFRESH_RATE_FREQUENCY);
timer_mod(s->refresh_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + NANOSECONDS_PER_SECOND / LCD_REFRESH_RATE_FREQUENCY);
}
static void ipod_touch_lcd_realize(DeviceState *dev, Error **errp)
@@ -152,7 +177,7 @@ static void ipod_touch_lcd_realize(DeviceState *dev, Error **errp)
qemu_console_resize(s->con, 320, 480);
// add mouse handler
//qemu_add_mouse_event_handler(ipod_touch_lcd_mouse_event, s, 1, "iPod Touch Touchscreen");
qemu_add_mouse_event_handler(ipod_touch_lcd_mouse_event, s, 1, "iPod Touch Touchscreen");
// initialize the refresh timer
s->refresh_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, refresh_timer_tick, s);
+2 -2
View File
@@ -338,8 +338,8 @@ static MTFrame *get_frame(IPodTouchMultitouchState *s, uint8_t event, float x, f
}
static void ipod_touch_multitouch_inform_frame_ready(IPodTouchMultitouchState *s) {
s->sysic->gpio_int_status[4] |= (1 << 27); // the multitouch interrupt bit is in group 4 (32 interrupts per group), and the 27th of the 4th group
qemu_irq_raise(s->sysic->gpio_irqs[4]);
s->sysic->gpio_int_status[3] |= (1 << 13); // the multitouch interrupt bit is in group 3 (32 interrupts per group), and the 13th of the 3th group
qemu_irq_raise(s->sysic->gpio_irqs[3]);
}
void ipod_touch_multitouch_on_touch(IPodTouchMultitouchState *s) {
+1 -1
View File
@@ -66,7 +66,7 @@ void sdio_exec_cmd(IPodTouchSDIOState *s)
frame_header->checksum = length ^ 0xffff;
g_queue_push_tail(s->rx_fifo, frame_header);
timer_mod(s->irq_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + NANOSECONDS_PER_SECOND / 50);
timer_mod(s->irq_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + NANOSECONDS_PER_SECOND / 100);
}
} else {
if(func == 0x1) {
+9
View File
@@ -50,6 +50,15 @@
#define S5L8720_FMSS_IRQ 0x36
#define S5L8720_SPI4_IRQ 0x37
// GPIO interrupts
#define S5L8900_GPIO_G0_IRQ 0x21
#define S5L8900_GPIO_G1_IRQ 0x20
#define S5L8900_GPIO_G2_IRQ 0x1F
#define S5L8900_GPIO_G3_IRQ 0x03
#define S5L8900_GPIO_G4_IRQ 0x02
const int S5L8900_GPIO_IRQS[5] = { S5L8900_GPIO_G0_IRQ, S5L8900_GPIO_G1_IRQ, S5L8900_GPIO_G2_IRQ, S5L8900_GPIO_G3_IRQ, S5L8900_GPIO_G4_IRQ };
#define IT2G_CPREG_VAR_NAME(name) cpreg_##name
#define IT2G_CPREG_VAR_DEF(name) uint64_t IT2G_CPREG_VAR_NAME(name)
+4
View File
@@ -7,6 +7,7 @@
#include "qemu/timer.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "hw/arm/ipod_touch_multitouch.h"
#define TYPE_IPOD_TOUCH_LCD "ipodtouch.lcd"
OBJECT_DECLARE_SIMPLE_TYPE(IPodTouchLCDState, IPOD_TOUCH_LCD)
@@ -19,6 +20,7 @@ typedef struct IPodTouchLCDState
MemoryRegion *sysmem;
MemoryRegion iomem;
QemuConsole *con;
IPodTouchMultitouchState *mt;
int invalidate;
MemoryRegionSection fbsection;
qemu_irq irq;
@@ -29,6 +31,8 @@ typedef struct IPodTouchLCDState
uint32_t w1_hspan;
uint32_t w1_display_depth_info;
uint32_t unknown1;
QEMUTimer *refresh_timer;
} IPodTouchLCDState;