From 01d152c0bfabadc6c93a39e465eb2f66f3f11527 Mon Sep 17 00:00:00 2001 From: Xinhao Zhang Date: Wed, 4 Nov 2020 21:37:09 +0800 Subject: hw/xen: Don't use '#' flag of printf format Fix code style. Don't use '#' flag of printf format ('%#') in format strings, use '0x' prefix instead Signed-off-by: Xinhao Zhang <zhangxinhao1@huawei.com> Signed-off-by: Kai Deng <dengkai1@huawei.com> Message-Id: <20201104133709.3326630-1-zhangxinhao1@huawei.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- hw/xen/xen_pt.c | 10 +++++----- hw/xen/xen_pt_config_init.c | 6 +++--- hw/xen/xen_pt_msi.c | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'hw') diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 6d359ee486..a5f3dd590c 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -489,7 +489,7 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s, uint16_t *cmd) pci_register_bar(&s->dev, i, type, &s->bar[i]); XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%08"PRIx64 - " base_addr=0x%08"PRIx64" type: %#x)\n", + " base_addr=0x%08"PRIx64" type: 0x%x)\n", i, r->size, r->base_addr, type); } @@ -578,7 +578,7 @@ static void xen_pt_check_bar_overlap(PCIBus *bus, PCIDevice *d, void *opaque) if (ranges_overlap(arg->addr, arg->size, r->addr, r->size)) { XEN_PT_WARN(&s->dev, "Overlapped to device [%02x:%02x.%d] Region: %i" - " (addr: %#"FMT_PCIBUS", len: %#"FMT_PCIBUS")\n", + " (addr: 0x%"FMT_PCIBUS", len: 0x%"FMT_PCIBUS")\n", pci_bus_num(bus), PCI_SLOT(d->devfn), PCI_FUNC(d->devfn), i, r->addr, r->size); arg->rc = true; @@ -618,8 +618,8 @@ static void xen_pt_region_update(XenPCIPassthroughState *s, pci_for_each_device(pci_get_bus(d), pci_dev_bus_num(d), xen_pt_check_bar_overlap, &args); if (args.rc) { - XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS - ", len: %#"FMT_PCIBUS") is overlapped.\n", + XEN_PT_WARN(d, "Region: %d (addr: 0x%"FMT_PCIBUS + ", len: 0x%"FMT_PCIBUS") is overlapped.\n", bar, sec->offset_within_address_space, int128_get64(sec->size)); } @@ -786,7 +786,7 @@ static void xen_pt_realize(PCIDevice *d, Error **errp) /* register real device */ XEN_PT_LOG(d, "Assigning real physical device %02x:%02x.%d" - " to devfn %#x\n", + " to devfn 0x%x\n", s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function, s->dev.devfn); diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index c8724cc7c8..c5c4e943a8 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -1622,7 +1622,7 @@ static int xen_pt_pcie_size_init(XenPCIPassthroughState *s, case PCI_EXP_TYPE_PCIE_BRIDGE: case PCI_EXP_TYPE_RC_EC: default: - XEN_PT_ERR(d, "Unsupported device/port type %#x.\n", type); + XEN_PT_ERR(d, "Unsupported device/port type 0x%x.\n", type); return -1; } } @@ -1645,11 +1645,11 @@ static int xen_pt_pcie_size_init(XenPCIPassthroughState *s, case PCI_EXP_TYPE_PCIE_BRIDGE: case PCI_EXP_TYPE_RC_EC: default: - XEN_PT_ERR(d, "Unsupported device/port type %#x.\n", type); + XEN_PT_ERR(d, "Unsupported device/port type 0x%x.\n", type); return -1; } } else { - XEN_PT_ERR(d, "Unsupported capability version %#x.\n", version); + XEN_PT_ERR(d, "Unsupported capability version 0x%x.\n", version); return -1; } diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c index fb4b887b92..b71563f98a 100644 --- a/hw/xen/xen_pt_msi.c +++ b/hw/xen/xen_pt_msi.c @@ -123,7 +123,7 @@ static int msi_msix_setup(XenPCIPassthroughState *s, *ppirq = XEN_PT_UNASSIGNED_PIRQ; } else { XEN_PT_LOG(&s->dev, "requested pirq %d for MSI%s" - " (vec: %#x, entry: %#x)\n", + " (vec: 0x%x, entry: 0x%x)\n", *ppirq, is_msix ? "-X" : "", gvec, msix_entry); } } @@ -142,7 +142,7 @@ static int msi_msix_setup(XenPCIPassthroughState *s, msix_entry, table_base); if (rc) { XEN_PT_ERR(&s->dev, - "Mapping of MSI%s (err: %i, vec: %#x, entry %#x)\n", + "Mapping of MSI%s (err: %i, vec: 0x%x, entry 0x%x)\n", is_msix ? "-X" : "", errno, gvec, msix_entry); return rc; } @@ -165,8 +165,8 @@ static int msi_msix_update(XenPCIPassthroughState *s, int rc = 0; uint64_t table_addr = 0; - XEN_PT_LOG(d, "Updating MSI%s with pirq %d gvec %#x gflags %#x" - " (entry: %#x)\n", + XEN_PT_LOG(d, "Updating MSI%s with pirq %d gvec 0x%x gflags 0x%x" + " (entry: 0x%x)\n", is_msix ? "-X" : "", pirq, gvec, gflags, msix_entry); if (is_msix) { @@ -208,11 +208,11 @@ static int msi_msix_disable(XenPCIPassthroughState *s, } if (is_binded) { - XEN_PT_LOG(d, "Unbind MSI%s with pirq %d, gvec %#x\n", + XEN_PT_LOG(d, "Unbind MSI%s with pirq %d, gvec 0x%x\n", is_msix ? "-X" : "", pirq, gvec); rc = xc_domain_unbind_msi_irq(xen_xc, xen_domid, gvec, pirq, gflags); if (rc) { - XEN_PT_ERR(d, "Unbinding of MSI%s failed. (err: %d, pirq: %d, gvec: %#x)\n", + XEN_PT_ERR(d, "Unbinding of MSI%s failed. (err: %d, pirq: %d, gvec: 0x%x)\n", is_msix ? "-X" : "", errno, pirq, gvec); return rc; } @@ -539,7 +539,7 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base) } if (id != PCI_CAP_ID_MSIX) { - XEN_PT_ERR(d, "Invalid id %#x base %#x\n", id, base); + XEN_PT_ERR(d, "Invalid id 0x%x base 0x%x\n", id, base); return -1; } @@ -582,7 +582,7 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base) XEN_PT_ERR(d, "Can't open /dev/mem: %s\n", strerror(errno)); goto error_out; } - XEN_PT_LOG(d, "table_off = %#x, total_entries = %d\n", + XEN_PT_LOG(d, "table_off = 0x%x, total_entries = %d\n", table_off, total_entries); msix->table_offset_adjust = table_off & 0x0fff; msix->phys_iomem_base = -- cgit v1.2.3-55-g7522 From f6a3c86ebd39aaedf1ebf89629ec91b5d44b670d Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 2 Dec 2020 14:20:38 +0100 Subject: hw/pci-host/pam: Replace magic number by PAM_REGIONS_COUNT definition While this change helps triskaidekaphobic developers, it is a good practice to avoid magic values and using constant definitions instead. Introduce the PAM_REGIONS_COUNT and use it. No logical change. Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Julia Suvorova <jusual@redhat.com> Message-Id: <20201202132038.1276404-1-philmd@redhat.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- hw/pci-host/pam.c | 2 +- hw/pci-host/q35.c | 2 +- include/hw/pci-host/i440fx.h | 2 +- include/hw/pci-host/pam.h | 2 ++ include/hw/pci-host/q35.h | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/pam.c b/hw/pci-host/pam.c index a496205783..454dd120db 100644 --- a/hw/pci-host/pam.c +++ b/hw/pci-host/pam.c @@ -62,7 +62,7 @@ void init_pam(DeviceState *dev, MemoryRegion *ram_memory, void pam_update(PAMMemoryRegion *pam, int idx, uint8_t val) { - assert(0 <= idx && idx <= 12); + assert(0 <= idx && idx < PAM_REGIONS_COUNT); memory_region_set_enabled(&pam->alias[pam->current], false); pam->current = (val >> ((!(idx & 1)) * 4)) & PAM_ATTR_MASK; diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index b67cb9c29f..2eb729dff5 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -641,7 +641,7 @@ static void mch_realize(PCIDevice *d, Error **errp) init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); - for (i = 0; i < 12; ++i) { + for (i = 0; i < ARRAY_SIZE(mch->pam_regions) - 1; ++i) { init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); diff --git a/include/hw/pci-host/i440fx.h b/include/hw/pci-host/i440fx.h index 6c16eaf876..24fd53942c 100644 --- a/include/hw/pci-host/i440fx.h +++ b/include/hw/pci-host/i440fx.h @@ -29,7 +29,7 @@ struct PCII440FXState { MemoryRegion *system_memory; MemoryRegion *pci_address_space; MemoryRegion *ram_memory; - PAMMemoryRegion pam_regions[13]; + PAMMemoryRegion pam_regions[PAM_REGIONS_COUNT]; MemoryRegion smram_region; MemoryRegion smram, low_smram; }; diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h index fec5cd35d6..c1fd06ba2a 100644 --- a/include/hw/pci-host/pam.h +++ b/include/hw/pci-host/pam.h @@ -80,6 +80,8 @@ #define SMRAM_C_BASE_SEG_MASK ((uint8_t)0x7) #define SMRAM_C_BASE_SEG ((uint8_t)0x2) /* hardwired to b010 */ +#define PAM_REGIONS_COUNT 13 + typedef struct PAMMemoryRegion { MemoryRegion alias[4]; /* index = PAM value */ unsigned current; diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index bbb9581765..ab989698ef 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -44,7 +44,7 @@ struct MCHPCIState { MemoryRegion *pci_address_space; MemoryRegion *system_memory; MemoryRegion *address_space_io; - PAMMemoryRegion pam_regions[13]; + PAMMemoryRegion pam_regions[PAM_REGIONS_COUNT]; MemoryRegion smram_region, open_high_smram; MemoryRegion smram, low_smram, high_smram; MemoryRegion tseg_blackhole, tseg_window; -- cgit v1.2.3-55-g7522 From f12985f14a05181b34b3cfb935b4136a05726423 Mon Sep 17 00:00:00 2001 From: Gan Qixin Date: Sun, 15 Nov 2020 20:35:03 +0800 Subject: ads7846: moves from the hw/display folder to the hw/input folder. ads7846 is a touch-screen controller that is an input device rather than a display device, so move it to the hw/input folder. Signed-off-by: Gan Qixin <ganqixin@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20201115123503.1110665-1-ganqixin@huawei.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- hw/arm/Kconfig | 2 +- hw/display/Kconfig | 3 - hw/display/ads7846.c | 186 ------------------------------------------------- hw/display/meson.build | 1 - hw/input/Kconfig | 3 + hw/input/ads7846.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/input/meson.build | 1 + 7 files changed, 191 insertions(+), 191 deletions(-) delete mode 100644 hw/display/ads7846.c create mode 100644 hw/input/ads7846.c (limited to 'hw') diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index eb8a8844cf..0a242e4c5d 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -156,7 +156,7 @@ config TOSA config SPITZ bool - select ADS7846 # display + select ADS7846 # touch-screen controller select MAX111X # A/D converter select WM8750 # audio codec select MAX7310 # GPIO expander diff --git a/hw/display/Kconfig b/hw/display/Kconfig index 15d59e10dc..ca46b5830e 100644 --- a/hw/display/Kconfig +++ b/hw/display/Kconfig @@ -9,9 +9,6 @@ config EDID config FW_CFG_DMA bool -config ADS7846 - bool - config VGA_CIRRUS bool default y if PCI_DEVICES diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c deleted file mode 100644 index 1d4e04a2dc..0000000000 --- a/hw/display/ads7846.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * TI ADS7846 / TSC2046 chip emulation. - * - * Copyright (c) 2006 Openedhand Ltd. - * Written by Andrzej Zaborowski <balrog@zabor.org> - * - * This code is licensed under the GNU GPL v2. - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. - */ - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/ssi/ssi.h" -#include "migration/vmstate.h" -#include "qemu/module.h" -#include "ui/console.h" -#include "qom/object.h" - -struct ADS7846State { - SSIPeripheral ssidev; - qemu_irq interrupt; - - int input[8]; - int pressure; - int noise; - - int cycle; - int output; -}; - -#define TYPE_ADS7846 "ads7846" -OBJECT_DECLARE_SIMPLE_TYPE(ADS7846State, ADS7846) - -/* Control-byte bitfields */ -#define CB_PD0 (1 << 0) -#define CB_PD1 (1 << 1) -#define CB_SER (1 << 2) -#define CB_MODE (1 << 3) -#define CB_A0 (1 << 4) -#define CB_A1 (1 << 5) -#define CB_A2 (1 << 6) -#define CB_START (1 << 7) - -#define X_AXIS_DMAX 3470 -#define X_AXIS_MIN 290 -#define Y_AXIS_DMAX 3450 -#define Y_AXIS_MIN 200 - -#define ADS_VBAT 2000 -#define ADS_VAUX 2000 -#define ADS_TEMP0 2000 -#define ADS_TEMP1 3000 -#define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15)) -#define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15)) -#define ADS_Z1POS(x, y) 600 -#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y)) - -static void ads7846_int_update(ADS7846State *s) -{ - if (s->interrupt) - qemu_set_irq(s->interrupt, s->pressure == 0); -} - -static uint32_t ads7846_transfer(SSIPeripheral *dev, uint32_t value) -{ - ADS7846State *s = ADS7846(dev); - - switch (s->cycle ++) { - case 0: - if (!(value & CB_START)) { - s->cycle = 0; - break; - } - - s->output = s->input[(value >> 4) & 7]; - - /* Imitate the ADC noise, some drivers expect this. */ - s->noise = (s->noise + 3) & 7; - switch ((value >> 4) & 7) { - case 1: s->output += s->noise ^ 2; break; - case 3: s->output += s->noise ^ 0; break; - case 4: s->output += s->noise ^ 7; break; - case 5: s->output += s->noise ^ 5; break; - } - - if (value & CB_MODE) - s->output >>= 4; /* 8 bits instead of 12 */ - - break; - case 1: - s->cycle = 0; - break; - } - return s->output; -} - -static void ads7846_ts_event(void *opaque, - int x, int y, int z, int buttons_state) -{ - ADS7846State *s = opaque; - - if (buttons_state) { - x = 0x7fff - x; - s->input[1] = ADS_XPOS(x, y); - s->input[3] = ADS_Z1POS(x, y); - s->input[4] = ADS_Z2POS(x, y); - s->input[5] = ADS_YPOS(x, y); - } - - if (s->pressure == !buttons_state) { - s->pressure = !!buttons_state; - - ads7846_int_update(s); - } -} - -static int ads7856_post_load(void *opaque, int version_id) -{ - ADS7846State *s = opaque; - - s->pressure = 0; - ads7846_int_update(s); - return 0; -} - -static const VMStateDescription vmstate_ads7846 = { - .name = "ads7846", - .version_id = 1, - .minimum_version_id = 1, - .post_load = ads7856_post_load, - .fields = (VMStateField[]) { - VMSTATE_SSI_PERIPHERAL(ssidev, ADS7846State), - VMSTATE_INT32_ARRAY(input, ADS7846State, 8), - VMSTATE_INT32(noise, ADS7846State), - VMSTATE_INT32(cycle, ADS7846State), - VMSTATE_INT32(output, ADS7846State), - VMSTATE_END_OF_LIST() - } -}; - -static void ads7846_realize(SSIPeripheral *d, Error **errp) -{ - DeviceState *dev = DEVICE(d); - ADS7846State *s = ADS7846(d); - - qdev_init_gpio_out(dev, &s->interrupt, 1); - - s->input[0] = ADS_TEMP0; /* TEMP0 */ - s->input[2] = ADS_VBAT; /* VBAT */ - s->input[6] = ADS_VAUX; /* VAUX */ - s->input[7] = ADS_TEMP1; /* TEMP1 */ - - /* We want absolute coordinates */ - qemu_add_mouse_event_handler(ads7846_ts_event, s, 1, - "QEMU ADS7846-driven Touchscreen"); - - ads7846_int_update(s); - - vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_ads7846, s); -} - -static void ads7846_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass); - - k->realize = ads7846_realize; - k->transfer = ads7846_transfer; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); -} - -static const TypeInfo ads7846_info = { - .name = TYPE_ADS7846, - .parent = TYPE_SSI_PERIPHERAL, - .instance_size = sizeof(ADS7846State), - .class_init = ads7846_class_init, -}; - -static void ads7846_register_types(void) -{ - type_register_static(&ads7846_info); -} - -type_init(ads7846_register_types) diff --git a/hw/display/meson.build b/hw/display/meson.build index dad3bd2b41..9d79e3951d 100644 --- a/hw/display/meson.build +++ b/hw/display/meson.build @@ -6,7 +6,6 @@ softmmu_ss.add(when: 'CONFIG_EDID', if_true: files('edid-generate.c', 'edid-regi softmmu_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: files('ramfb.c')) softmmu_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: files('ramfb-standalone.c')) -softmmu_ss.add(when: 'CONFIG_ADS7846', if_true: files('ads7846.c')) softmmu_ss.add(when: 'CONFIG_VGA_CIRRUS', if_true: files('cirrus_vga.c')) softmmu_ss.add(when: ['CONFIG_VGA_CIRRUS', 'CONFIG_VGA_ISA'], if_true: files('cirrus_vga_isa.c')) softmmu_ss.add(when: 'CONFIG_G364FB', if_true: files('g364fb.c')) diff --git a/hw/input/Kconfig b/hw/input/Kconfig index 64f14daabf..55865bb386 100644 --- a/hw/input/Kconfig +++ b/hw/input/Kconfig @@ -1,6 +1,9 @@ config ADB bool +config ADS7846 + bool + config LM832X bool depends on I2C diff --git a/hw/input/ads7846.c b/hw/input/ads7846.c new file mode 100644 index 0000000000..1d4e04a2dc --- /dev/null +++ b/hw/input/ads7846.c @@ -0,0 +1,186 @@ +/* + * TI ADS7846 / TSC2046 chip emulation. + * + * Copyright (c) 2006 Openedhand Ltd. + * Written by Andrzej Zaborowski <balrog@zabor.org> + * + * This code is licensed under the GNU GPL v2. + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ + +#include "qemu/osdep.h" +#include "hw/irq.h" +#include "hw/ssi/ssi.h" +#include "migration/vmstate.h" +#include "qemu/module.h" +#include "ui/console.h" +#include "qom/object.h" + +struct ADS7846State { + SSIPeripheral ssidev; + qemu_irq interrupt; + + int input[8]; + int pressure; + int noise; + + int cycle; + int output; +}; + +#define TYPE_ADS7846 "ads7846" +OBJECT_DECLARE_SIMPLE_TYPE(ADS7846State, ADS7846) + +/* Control-byte bitfields */ +#define CB_PD0 (1 << 0) +#define CB_PD1 (1 << 1) +#define CB_SER (1 << 2) +#define CB_MODE (1 << 3) +#define CB_A0 (1 << 4) +#define CB_A1 (1 << 5) +#define CB_A2 (1 << 6) +#define CB_START (1 << 7) + +#define X_AXIS_DMAX 3470 +#define X_AXIS_MIN 290 +#define Y_AXIS_DMAX 3450 +#define Y_AXIS_MIN 200 + +#define ADS_VBAT 2000 +#define ADS_VAUX 2000 +#define ADS_TEMP0 2000 +#define ADS_TEMP1 3000 +#define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15)) +#define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15)) +#define ADS_Z1POS(x, y) 600 +#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y)) + +static void ads7846_int_update(ADS7846State *s) +{ + if (s->interrupt) + qemu_set_irq(s->interrupt, s->pressure == 0); +} + +static uint32_t ads7846_transfer(SSIPeripheral *dev, uint32_t value) +{ + ADS7846State *s = ADS7846(dev); + + switch (s->cycle ++) { + case 0: + if (!(value & CB_START)) { + s->cycle = 0; + break; + } + + s->output = s->input[(value >> 4) & 7]; + + /* Imitate the ADC noise, some drivers expect this. */ + s->noise = (s->noise + 3) & 7; + switch ((value >> 4) & 7) { + case 1: s->output += s->noise ^ 2; break; + case 3: s->output += s->noise ^ 0; break; + case 4: s->output += s->noise ^ 7; break; + case 5: s->output += s->noise ^ 5; break; + } + + if (value & CB_MODE) + s->output >>= 4; /* 8 bits instead of 12 */ + + break; + case 1: + s->cycle = 0; + break; + } + return s->output; +} + +static void ads7846_ts_event(void *opaque, + int x, int y, int z, int buttons_state) +{ + ADS7846State *s = opaque; + + if (buttons_state) { + x = 0x7fff - x; + s->input[1] = ADS_XPOS(x, y); + s->input[3] = ADS_Z1POS(x, y); + s->input[4] = ADS_Z2POS(x, y); + s->input[5] = ADS_YPOS(x, y); + } + + if (s->pressure == !buttons_state) { + s->pressure = !!buttons_state; + + ads7846_int_update(s); + } +} + +static int ads7856_post_load(void *opaque, int version_id) +{ + ADS7846State *s = opaque; + + s->pressure = 0; + ads7846_int_update(s); + return 0; +} + +static const VMStateDescription vmstate_ads7846 = { + .name = "ads7846", + .version_id = 1, + .minimum_version_id = 1, + .post_load = ads7856_post_load, + .fields = (VMStateField[]) { + VMSTATE_SSI_PERIPHERAL(ssidev, ADS7846State), + VMSTATE_INT32_ARRAY(input, ADS7846State, 8), + VMSTATE_INT32(noise, ADS7846State), + VMSTATE_INT32(cycle, ADS7846State), + VMSTATE_INT32(output, ADS7846State), + VMSTATE_END_OF_LIST() + } +}; + +static void ads7846_realize(SSIPeripheral *d, Error **errp) +{ + DeviceState *dev = DEVICE(d); + ADS7846State *s = ADS7846(d); + + qdev_init_gpio_out(dev, &s->interrupt, 1); + + s->input[0] = ADS_TEMP0; /* TEMP0 */ + s->input[2] = ADS_VBAT; /* VBAT */ + s->input[6] = ADS_VAUX; /* VAUX */ + s->input[7] = ADS_TEMP1; /* TEMP1 */ + + /* We want absolute coordinates */ + qemu_add_mouse_event_handler(ads7846_ts_event, s, 1, + "QEMU ADS7846-driven Touchscreen"); + + ads7846_int_update(s); + + vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_ads7846, s); +} + +static void ads7846_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass); + + k->realize = ads7846_realize; + k->transfer = ads7846_transfer; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + +static const TypeInfo ads7846_info = { + .name = TYPE_ADS7846, + .parent = TYPE_SSI_PERIPHERAL, + .instance_size = sizeof(ADS7846State), + .class_init = ads7846_class_init, +}; + +static void ads7846_register_types(void) +{ + type_register_static(&ads7846_info); +} + +type_init(ads7846_register_types) diff --git a/hw/input/meson.build b/hw/input/meson.build index e7285b15ae..0042c3f0dc 100644 --- a/hw/input/meson.build +++ b/hw/input/meson.build @@ -1,5 +1,6 @@ softmmu_ss.add(files('hid.c')) softmmu_ss.add(when: 'CONFIG_ADB', if_true: files('adb.c', 'adb-mouse.c', 'adb-kbd.c')) +softmmu_ss.add(when: 'CONFIG_ADS7846', if_true: files('ads7846.c')) softmmu_ss.add(when: 'CONFIG_LM832X', if_true: files('lm832x.c')) softmmu_ss.add(when: 'CONFIG_PCKBD', if_true: files('pckbd.c')) softmmu_ss.add(when: 'CONFIG_PL050', if_true: files('pl050.c')) -- cgit v1.2.3-55-g7522