From nobody Fri May 3 17:19:23 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1669781679; cv=none; d=zohomail.com; s=zohoarc; b=eWI+nqT2P4YEryk3fKhIW1gQvzlklW1bluYNl3/2GWrM/gokNja/+gakp5jqUrvtdWgQm+DAEUj6SAvWAnn1KxuMyzuqm8zffMMXEzcO/4gemsz0NQabztBZj4JHFZpnX8++Dy8E7wmWLGkTvaS61Qbu3+sA0w6h8JH6uGnV4iM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1669781679; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=EbT+UVaeZt4w43R4RUSImS3lwlxemhcNRb3OmJo0aSM=; b=F2/B1SLxSEYqDOOf1z+wgQy2nF6WAYEJ6M4ZtN2Q4Ofw2SYWFc43A0gkmakW2ztrKH9TtuYnqifn/RCnLj7OUvSPl5vdMRl9YHaPcTbvaHvoSErg2iB9Fu2AjlF71mgRA62xwqRozZmL1LIT70UiGY/UUki8sMymwWXzz+GcpuQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1669781679890921.2483722515246; Tue, 29 Nov 2022 20:14:39 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p0EU1-00031h-G2; Tue, 29 Nov 2022 23:14:05 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p0ETz-000314-CX for qemu-devel@nongnu.org; Tue, 29 Nov 2022 23:14:03 -0500 Received: from mail-lj1-x236.google.com ([2a00:1450:4864:20::236]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p0ETw-00024y-GT for qemu-devel@nongnu.org; Tue, 29 Nov 2022 23:14:02 -0500 Received: by mail-lj1-x236.google.com with SMTP id h10so2839508ljk.11 for ; Tue, 29 Nov 2022 20:14:00 -0800 (PST) Received: from front.loc ([80.83.238.100]) by smtp.googlemail.com with ESMTPSA id f27-20020a19381b000000b004a25468d86asm81737lfa.68.2022.11.29.20.13.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Nov 2022 20:13:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EbT+UVaeZt4w43R4RUSImS3lwlxemhcNRb3OmJo0aSM=; b=pKLaSbDvpcvvHjMnbQy1cxB62DC9psPP4oPlSIjMprnjqbEoa8AjH0iZtHPQVN3mrG byOv8qCU4B65oEmmjTUZeHMCXKOMiweF4sIsZTJQLbyIL0s4lmmpjAlsvtSnP3JvlnWJ tHP5fCPtg76nC5bvxJh2Ozmd7f049Ia0QzR6TDTpt1bdUc+z7g28163fBjNzHDryuPH3 80p5vO6CnYa4mDORjECLXeYDEgh7dRZUGV4/AOt6w+ikncgjVutiElY3m+QW7kzlfN8f +FLhCz/U+8Pzq+aSnwJxfOyrIR206LIQtyxKVoUSFVnP45jq3lo60k8SoKW6Ub+rBPW9 GKeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EbT+UVaeZt4w43R4RUSImS3lwlxemhcNRb3OmJo0aSM=; b=cefCAZAo+dNCBrlko442aaPAfShFiteN9Kcf/NIhn4SdcYx34/P9U4Sq++X1tWpGOR 0MA75OFSBMiIOSIU0ha5dPmGR6cOXm3pP+y8KNueEe65vzYI6iFQ/QZ+CttTRdnBNroV dgcqnnSw256v/92TE6ghD+4+h8uzDcz5pQiIDqU31S+N9R3/HwoMfPow5d49n1lSdLyS rUHtRongYJBweUDwfVAdCHci+KTHAqBC3AyBtWGeedpkoIY53eVJb6Xwy+E3A1yOS8D6 wXRCv+hoEmjkz1zvFXhLpjdTFo2xM8VpqcP19K1llcvNONoayogAegDrFlkiTsva1FfV rCtw== X-Gm-Message-State: ANoB5pnX8oI5vjv1382P7HeVGO5Km0A9Xms0LtjBpPxGHmgKW7KNEFz4 D0G+OQ6SPeyTUa9OK8ouihBNpi26qYA= X-Google-Smtp-Source: AA0mqf6qdhWsxkL2+94BMISq48N/eV1mIyQMmo0pWPIB4kvaruzEyfuwav3K3Np9dblHIlxuMh87Cw== X-Received: by 2002:a2e:2c01:0:b0:279:926e:c9b9 with SMTP id s1-20020a2e2c01000000b00279926ec9b9mr7524417ljs.170.1669781638344; Tue, 29 Nov 2022 20:13:58 -0800 (PST) From: Evgeny Ermakov To: qemu-devel@nongnu.org Cc: Evgeny Ermakov Subject: [PATCH 1/2] hw/char: Add STM32F7 peripheral: USART Date: Wed, 30 Nov 2022 15:12:58 +1100 Message-Id: <20221130041259.12032-2-evgeny.v.ermakov@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221130041259.12032-1-evgeny.v.ermakov@gmail.com> References: <20221130041259.12032-1-evgeny.v.ermakov@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::236; envelope-from=evgeny.v.ermakov@gmail.com; helo=mail-lj1-x236.google.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_SORBS_WEB=1.5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1669781681393100003 Content-Type: text/plain; charset="utf-8" Signed-off-by: Evgeny Ermakov --- include/hw/char/stm32f7xx_usart.h | 30 +++ hw/char/stm32f7xx_usart.c | 361 ++++++++++++++++++++++++++++++ hw/arm/Kconfig | 1 + hw/char/Kconfig | 3 + hw/char/meson.build | 1 + hw/char/trace-events | 4 + 6 files changed, 400 insertions(+) create mode 100644 include/hw/char/stm32f7xx_usart.h create mode 100644 hw/char/stm32f7xx_usart.c diff --git a/include/hw/char/stm32f7xx_usart.h b/include/hw/char/stm32f7xx_= usart.h new file mode 100644 index 0000000000..ec005be8d8 --- /dev/null +++ b/include/hw/char/stm32f7xx_usart.h @@ -0,0 +1,30 @@ +/* + * STM32F7XX Universal synchronous/asynchronous receiver transmitter (USAR= T) + * + * Copyright (c) 2022 Evgeny Ermakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_CHAR_STM32F7XX_USART_H +#define HW_CHAR_STM32F7XX_USART_H + +#include "hw/arm/stm32f.h" +#include "chardev/char-fe.h" + +#define TYPE_STM32F7XX_USART "stm32f7xx-usart" +OBJECT_DECLARE_SIMPLE_TYPE(STM32F7XXUSARTState, STM32F7XX_USART) + +#define STM32F7XX_USART_R_MAX 11 + +struct STM32F7XXUSARTState { + /*< private >*/ + STM32FPeripheralState parent_obj; + + uint32_t regs[STM32F7XX_USART_R_MAX]; + + CharBackend chr; + qemu_irq irq; +}; + +#endif /* HW_CHAR_STM32F7XX_USART_H */ diff --git a/hw/char/stm32f7xx_usart.c b/hw/char/stm32f7xx_usart.c new file mode 100644 index 0000000000..122781705a --- /dev/null +++ b/hw/char/stm32f7xx_usart.c @@ -0,0 +1,361 @@ +/* + * STM32F7XX Universal synchronous/asynchronous receiver transmitter (USAR= T) + * + * Reference documents: + * - Reference manual RM0385 + * "STM32F75xxx and stm32f74xxx advanced Arm(R)-based 32-bit MCUs" + * - Reference manual RM0410 + * "STM32F76xxx and STM32F77xxx advanced Arm(R)-based 32-bit MCUs" + * + * Copyright (c) 2022 Evgeny Ermakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/char/stm32f7xx_usart.h" +#include "hw/irq.h" +#include "hw/qdev-properties-system.h" +#include "hw/registerfields.h" +#include "migration/vmstate.h" +#include "qemu/log.h" +#include "trace.h" + +#ifndef STM_USART_ERR_DEBUG +#define STM_USART_ERR_DEBUG 0 +#endif + +#define DB_PRINT_L(lvl, fmt, args...) \ + do { \ + if (STM_USART_ERR_DEBUG >=3D lvl) { \ + qemu_log("%s: " fmt, __func__, ## args); \ + } \ + } while (0) + +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) + +REG32(CR1, 0x00) + /* reserved: 31:29, 1 */ + FIELD(CR1, M1, 28, 1) + FIELD(CR1, EOBIE, 27, 1) + FIELD(CR1, RTOIE, 26, 1) + FIELD(CR1, DEAT, 21, 5) + FIELD(CR1, DEDT, 16, 5) + FIELD(CR1, OVER8, 15, 1) + FIELD(CR1, CMIE, 14, 1) + FIELD(CR1, MME, 13, 1) + FIELD(CR1, M0, 12, 1) + FIELD(CR1, WAKE, 11, 1) + FIELD(CR1, PCE, 10, 1) + FIELD(CR1, PS, 9, 1) + FIELD(CR1, PEIE, 8, 1) + FIELD(CR1, TXEIE, 7, 1) + FIELD(CR1, TCIE, 6, 1) + FIELD(CR1, RXNEIE, 5, 1) + FIELD(CR1, IDLEIE, 4, 1) + FIELD(CR1, TE, 3, 1) + FIELD(CR1, RE, 2, 1) + FIELD(CR1, UE, 0, 1) +REG32(CR2, 0x04) + /* reserved: 7, 3:0 */ + FIELD(CR2, ADD, 24, 8) + FIELD(CR2, RTOEN, 23, 1) + FIELD(CR2, ABRMOD, 21, 2) + FIELD(CR2, ABREN, 20, 1) + FIELD(CR2, MSBFIRST, 19, 1) + FIELD(CR2, DATAINV, 18, 1) + FIELD(CR2, TXINV, 17, 1) + FIELD(CR2, RXINV, 16, 1) + FIELD(CR2, SWAP, 15, 1) + FIELD(CR2, LINEN, 14, 1) + FIELD(CR2, STOP, 12, 2) + FIELD(CR2, CLKEN, 11, 1) + FIELD(CR2, CPOL, 10, 1) + FIELD(CR2, CPHA, 9, 1) + FIELD(CR2, LBCL, 8, 1) + FIELD(CR2, LBDIE, 6, 1) + FIELD(CR2, LBDL, 5, 1) + FIELD(CR2, ADDM7, 4, 1) +REG32(CR3, 0x08) + /* reserved: 31:25, 16 */ + FIELD(CR3, TCBGTIE, 24, 1) + FIELD(CR3, UCESM, 23, 1) + FIELD(CR3, WUFIE, 22, 1) + FIELD(CR3, WUS, 20, 2) + FIELD(CR3, SCARCNT, 17, 3) + FIELD(CR3, DEP, 15, 1) + FIELD(CR3, DEM, 14, 1) + FIELD(CR3, DDRE, 13, 1) + FIELD(CR3, OVRDIS, 12, 1) + FIELD(CR3, ONEBIT, 11, 1) + FIELD(CR3, CTSIE, 10, 1) + FIELD(CR3, CTSE, 9, 1) + FIELD(CR3, RTSE, 8, 1) + FIELD(CR3, DMAT, 7, 1) + FIELD(CR3, DMAR, 6, 1) + FIELD(CR3, SCEN, 5, 1) + FIELD(CR3, NACK, 4, 1) + FIELD(CR3, HDSEL, 3, 1) + FIELD(CR3, IRLP, 2, 1) + FIELD(CR3, IREN, 1, 1) + FIELD(CR3, EIE, 0, 1) +REG32(BRR, 0x0c) + /* reserved: 31:16 */ + FIELD(BRR, BRR, 0, 15) +REG32(GTPR, 0x10) + /* reserved: 31:16 */ + FIELD(GTPR, GT, 8, 8) + FIELD(GTPR, PSC, 0, 8) +REG32(RTOR, 0x14) + FIELD(RTOR, BLEN, 24, 8) + FIELD(RTOR, RTO, 0, 24) +REG32(RQR, 0x18) + /* reserved: 31:5 */ + FIELD(RQR, TXFRQ, 4, 1) + FIELD(RQR, RXFRQ, 3, 1) + FIELD(RQR, MMRQ, 2, 1) + FIELD(RQR, SBKRQ, 1, 1) + FIELD(RQR, ABRRQ, 0, 1) +REG32(ISR, 0x1c) + /* reserved: 31:26, 24:23, 13 */ + FIELD(ISR, TCBGT, 25, 1) + FIELD(ISR, REACK, 22, 1) + FIELD(ISR, TEACK, 21, 1) + FIELD(ISR, WUF, 20, 1) + FIELD(ISR, RWU, 19, 1) + FIELD(ISR, SBKF, 18, 1) + FIELD(ISR, CMF, 17, 1) + FIELD(ISR, BUSY, 16, 1) + FIELD(ISR, ABRF, 15, 1) + FIELD(ISR, ABRE, 14, 1) + FIELD(ISR, EOBF, 12, 1) + FIELD(ISR, RTOF, 11, 1) + FIELD(ISR, CTS, 10, 1) + FIELD(ISR, CTSIF, 9, 1) + FIELD(ISR, LBDF, 8, 1) + FIELD(ISR, TXE, 7, 1) + FIELD(ISR, TC, 6, 1) + FIELD(ISR, RXNE, 5, 1) + FIELD(ISR, IDLE, 4, 1) + FIELD(ISR, ORE, 3, 1) + FIELD(ISR, NF, 2, 1) + FIELD(ISR, FE, 1, 1) + FIELD(ISR, PE, 0, 1) +REG32(ICR, 0x20) + /* reserved: 31:21, 19:18, 16:13, 10, 5 */ + FIELD(ICR, WUCF, 20, 1) + FIELD(ICR, CMCF, 17, 1) + FIELD(ICR, EOBCF, 12, 1) + FIELD(ICR, RTOCF, 11, 1) + FIELD(ICR, CTSCF, 9, 1) + FIELD(ICR, LBDCF, 8, 1) + FIELD(ICR, TCBGTCF, 7, 1) + FIELD(ICR, TCCF, 6, 1) + FIELD(ICR, IDLECF, 4, 1) + FIELD(ICR, ORECF, 3, 1) + FIELD(ICR, NCF, 2, 1) + FIELD(ICR, FECF, 1, 1) + FIELD(ICR, PECF, 0, 1) +REG32(RDR, 0x24) + /* reserved: 31:9 */ + FIELD(RDR, RDR, 0, 9) +REG32(TDR, 0x28) + /* reserved: 31:9 */ + FIELD(TDR, TDR, 0, 9) + + +static int stm32f7xx_usart_can_receive(void *opaque) +{ + /* STM32F7XXUSARTState *s =3D opaque; */ + + /* if (!(s->usart_sr & USART_SR_RXNE)) { */ + /* return 1; */ + /* } */ + + return 0; +} + +static void stm32f7xx_usart_receive(void *opaque, const uint8_t *buf, int = size) +{ +#if 0 + STM32F7XXUSARTState *s =3D opaque; + + if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) { + /* USART not enabled - drop the chars */ + DB_PRINT("Dropping the chars\n"); + return; + } + + s->usart_dr =3D *buf; + s->usart_sr |=3D USART_SR_RXNE; + + if (s->usart_cr1 & USART_CR1_RXNEIE) { + qemu_set_irq(s->irq, 1); + } + + DB_PRINT("Receiving: %c\n", s->usart_dr); +#endif +} + +static uint32_t stm32f7xx_usart_read(void *opaque, hwaddr addr, + unsigned int size) +{ + STM32F7XXUSARTState *s =3D opaque; + + trace_stm32f7xx_usart_read(addr); + + switch (addr) { + case A_CR1: + return s->regs[R_CR1]; + case A_CR2: + return s->regs[R_CR2]; + case A_CR3: + return s->regs[R_CR3]; + case A_BRR: + return s->regs[R_BRR]; + case A_GTPR: + return s->regs[R_GTPR]; + case A_RTOR: + return s->regs[R_RTOR]; + case A_RQR: + return s->regs[R_RQR]; + case A_ISR: + return s->regs[R_ISR]; + case A_ICR: + return s->regs[R_ICR]; + case A_RDR: + return s->regs[R_RDR]; + case A_TDR: + return s->regs[R_TDR]; + default: + STM32F_LOG_BAD_OFFSET(); + break; + } + + return 0; +} + +static void stm32f7xx_usart_write(void *opaque, hwaddr addr, + uint32_t value, unsigned int size) +{ + STM32F7XXUSARTState *s =3D opaque; + /* unsigned char ch; */ + + trace_stm32f7xx_usart_write(addr, value); + + switch (addr) { + case A_CR1: + s->regs[R_CR1] =3D value; + break; + case A_CR2: + s->regs[R_CR2] =3D value; + break; + case A_CR3: + s->regs[R_CR3] =3D value; + break; + case A_BRR: + s->regs[R_BRR] =3D value; + break; + case A_GTPR: + s->regs[R_GTPR] =3D value; + break; + case A_RTOR: + s->regs[R_RTOR] =3D value; + break; + case A_RQR: + s->regs[R_RQR] =3D value; + break; + case A_ISR: + s->regs[R_ISR] =3D value; + break; + case A_ICR: + s->regs[R_ICR] =3D value; + break; + case A_RDR: + s->regs[R_RDR] =3D value; + break; + case A_TDR: + if (value < 0xf000) { + uint8_t ch =3D value; + /* XXX this blocks entire thread. Rewrite to use + * qemu_chr_fe_write and background I/O callbacks */ + qemu_chr_fe_write_all(&s->chr, &ch, 1); + /* XXX I/O are currently synchronous, making it impossible for + software to observe transient states where TXE or TC aren't + set. Unlike TXE however, which is read-only, software may + clear TC by writing 0 to the SR register, so set it again + on each write. */ + /* s->usart_sr |=3D USART_SR_TC; */ + } + break; + default: + STM32F_LOG_BAD_OFFSET(); + break; + } +} + +static void stm32f7xx_usart_reset_enter(Object *obj, ResetType type) +{ + STM32F7XXUSARTState *s =3D STM32F7XX_USART(obj); + + memset(s->regs, 0, sizeof(s->regs)); + s->regs[R_ISR] =3D 0x020000c0; +} + +static void stm32f7xx_usart_reset_exit(Object *obj) +{ + STM32F7XXUSARTState *s =3D STM32F7XX_USART(obj); + + qemu_set_irq(s->irq, 0); +} + +static void stm32f7xx_usart_init(Object *obj) +{ + STM32F7XXUSARTState *s =3D STM32F7XX_USART(obj); + + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); +} + +static void stm32f7xx_usart_realize(DeviceState *dev, Error **errp) +{ + STM32F7XXUSARTState *s =3D STM32F7XX_USART(dev); + + qemu_chr_fe_set_handlers(&s->chr, stm32f7xx_usart_can_receive, + stm32f7xx_usart_receive, NULL, NULL, + s, NULL, true); +} + +static Property stm32f7xx_usart_properties[] =3D { + DEFINE_PROP_CHR("chardev", STM32F7XXUSARTState, chr), + DEFINE_PROP_END_OF_LIST() +}; + +static void stm32f7xx_usart_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + STM32FPeripheralClass *pc =3D STM32F_PERIPHERAL_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + dc->realize =3D stm32f7xx_usart_realize; + device_class_set_props(dc, stm32f7xx_usart_properties); + rc->phases.enter =3D stm32f7xx_usart_reset_enter; + rc->phases.exit =3D stm32f7xx_usart_reset_exit; + pc->mmio_size =3D 0x400; + pc->mmio_read =3D stm32f7xx_usart_read; + pc->mmio_write =3D stm32f7xx_usart_write; +} + +static const TypeInfo stm32f7xx_usart_info =3D { + .name =3D TYPE_STM32F7XX_USART, + .parent =3D TYPE_STM32F_PERIPHERAL, + .instance_size =3D sizeof(STM32F7XXUSARTState), + .instance_init =3D stm32f7xx_usart_init, + .class_init =3D stm32f7xx_usart_class_init, +}; + +static void stm32f7xx_usart_register_types(void) +{ + type_register_static(&stm32f7xx_usart_info); +} + +type_init(stm32f7xx_usart_register_types) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index c2f6e748b0..02dfbcb99a 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -376,6 +376,7 @@ config STM32F405_SOC config STM32F7XX_SOC bool select STM32F + select STM32F7XX_USART =20 config XLNX_ZYNQMP_ARM bool diff --git a/hw/char/Kconfig b/hw/char/Kconfig index 6b6cf2fc1d..22b1cf8062 100644 --- a/hw/char/Kconfig +++ b/hw/char/Kconfig @@ -41,6 +41,9 @@ config VIRTIO_SERIAL config STM32F2XX_USART bool =20 +config STM32F7XX_USART + bool + config CMSDK_APB_UART bool =20 diff --git a/hw/char/meson.build b/hw/char/meson.build index 7b594f51b8..6230750375 100644 --- a/hw/char/meson.build +++ b/hw/char/meson.build @@ -31,6 +31,7 @@ softmmu_ss.add(when: 'CONFIG_RENESAS_SCI', if_true: files= ('renesas_sci.c')) softmmu_ss.add(when: 'CONFIG_SIFIVE_UART', if_true: files('sifive_uart.c')) softmmu_ss.add(when: 'CONFIG_SH_SCI', if_true: files('sh_serial.c')) softmmu_ss.add(when: 'CONFIG_STM32F2XX_USART', if_true: files('stm32f2xx_u= sart.c')) +softmmu_ss.add(when: 'CONFIG_STM32F7XX_USART', if_true: files('stm32f7xx_u= sart.c')) softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_MMUART', if_true: files('mchp_pfso= c_mmuart.c')) =20 specific_ss.add(when: 'CONFIG_HTIF', if_true: files('riscv_htif.c')) diff --git a/hw/char/trace-events b/hw/char/trace-events index 2ecb36232e..41fa3c0b46 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -105,3 +105,7 @@ cadence_uart_baudrate(unsigned baudrate) "baudrate %u" # sh_serial.c sh_serial_read(char *id, unsigned size, uint64_t offs, uint64_t val) " %s = size %d offs 0x%02" PRIx64 " -> 0x%02" PRIx64 sh_serial_write(char *id, unsigned size, uint64_t offs, uint64_t val) "%s = size %d offs 0x%02" PRIx64 " <- 0x%02" PRIx64 + +# stm32f7xx_usart.c +stm32f7xx_usart_read(uint64_t addr) " addr: 0x%02" PRIx64 +stm32f7xx_usart_write(uint64_t addr, uint64_t data) "addr: 0x%02" PRIx64 "= val: 0x%" PRIx64 --=20 2.38.1 From nobody Fri May 3 17:19:23 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1669781697; cv=none; d=zohomail.com; s=zohoarc; b=Edh0hYsm24OAhbmuja1nCVFloNK7j0iQylT2DAtoeONHJQlk1ZcdhW0LI60Yf/8TaDpLI4DnXm6qmGzjpis9y7kml9FSbKUAb1SNS4VZrXzdfgIRN5dQeHGseS+Udyp64Wnc07tQwGIF+xJqmrQuC/uyip+V7qvYWGJ44Gy5a7I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1669781697; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=r/nMGcwmelHTeaPt7Ul1UnwKfhIhG9Ik4jEhGde7u1Y=; b=Vhn3DH5okdBUEcNzmjLN77DEp6b27EH5PoCguZWK+BYvjiS+dFpVOiGv2714iMt2G9mwhsmgeGlBsTBnmQ2qhHtn3NAoIZyAmck6tkBXGKPpjcGWBXWP3JWX2U9SumpMq9JI/7CtpHY/YqL+O1QSt+F+WTVS98xNd+zgY7luVfE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1669781697507625.6972233353234; Tue, 29 Nov 2022 20:14:57 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p0EU7-00032H-HI; Tue, 29 Nov 2022 23:14:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p0EU6-00031t-12 for qemu-devel@nongnu.org; Tue, 29 Nov 2022 23:14:10 -0500 Received: from mail-lf1-x12d.google.com ([2a00:1450:4864:20::12d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p0ETy-000254-MK for qemu-devel@nongnu.org; Tue, 29 Nov 2022 23:14:09 -0500 Received: by mail-lf1-x12d.google.com with SMTP id f13so25095495lfa.6 for ; Tue, 29 Nov 2022 20:14:02 -0800 (PST) Received: from front.loc ([80.83.238.100]) by smtp.googlemail.com with ESMTPSA id f27-20020a19381b000000b004a25468d86asm81737lfa.68.2022.11.29.20.13.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Nov 2022 20:14:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=r/nMGcwmelHTeaPt7Ul1UnwKfhIhG9Ik4jEhGde7u1Y=; b=H8O44t7iNRLfzaeEvAwxsEXpRaAYkRtO3a29XqaWZCzrumgGLsU7XBKLUNgSWrc5ed MEM8CaAXIJhYtAfDDcPMGalqqORqbdpzG1QTlhN/tMVrzXL9K6zLYssatnfYbtLimzyl 01mpSIs7j5h089/K5Siq+eUzObC4QYRuhIAulP2SkYX3hgK/OTYfic2xQab80L9SSDGR DG1KtiQicqahPJHU+QKGXXpCRSF5pxPq8Ter7IIxEYOLvR3kjMzWSF+gUHYyYi8UynwO uiEAQceby6KHBFLrDuW+DKllSidOPeBYSNreErxrMDsrQp9OLkiSBeWzfbXYYmSTv8mX S1vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=r/nMGcwmelHTeaPt7Ul1UnwKfhIhG9Ik4jEhGde7u1Y=; b=Y+Nhd/t+ZjhiaLKqbaPeJI4I+3SAwSU8X2fA+wEJA8eCh66/0AMLPGKpHLKn+RA2Rt P3gdkjvmpHcgxQAykyhvs6SC0fqYFtKBMHHjgCWsBZppnqb45C4Gq3Pw65gTqi0MOGbq 8dUBalRpX49lRwOsuhwawoOYoqppJbMImOZvSUCO7WNkvCDlUuuAes3Miz0jaZ2ubu7M xYWNlBWKxU6tPmlYHfFQgcjOQJpM3cpdd0I+8UZeD17k9zhrD/CwyY8OigSWl13y/7pv Nbj0eseoC/eQ3/GBseyFTC65FpC1/6DJzaIsQC+PIk2cZWNk+JnylTEPXl/ECKlKLBy+ VEhA== X-Gm-Message-State: ANoB5pmLMFzojreZbFmE9RKs4dDvLnxep1GLktSNIlQZDvh0IBOK0llO paIvNxIgQ9kmSWqcYHiPimhPUrA8HwI= X-Google-Smtp-Source: AA0mqf4FHJlUnM9vfXqDBfmpETG5r0ewUvRc3sdjt8G5Pw421IxZeQC5zLZ2OCY0FYIxRYiVMtXUWw== X-Received: by 2002:a19:ca55:0:b0:4b5:2ae5:d3bd with SMTP id h21-20020a19ca55000000b004b52ae5d3bdmr1379832lfj.46.1669781640553; Tue, 29 Nov 2022 20:14:00 -0800 (PST) From: Evgeny Ermakov To: qemu-devel@nongnu.org Cc: Evgeny Ermakov Subject: [PATCH 2/2] hw/input: Add FT5336 touch controller Date: Wed, 30 Nov 2022 15:12:59 +1100 Message-Id: <20221130041259.12032-3-evgeny.v.ermakov@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221130041259.12032-1-evgeny.v.ermakov@gmail.com> References: <20221130041259.12032-1-evgeny.v.ermakov@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::12d; envelope-from=evgeny.v.ermakov@gmail.com; helo=mail-lf1-x12d.google.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_SORBS_WEB=1.5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1669781699440100003 Content-Type: text/plain; charset="utf-8" Signed-off-by: Evgeny Ermakov --- include/hw/input/ft5336.h | 14 ++ hw/input/ft5336.c | 357 ++++++++++++++++++++++++++++++++++++++ hw/input/Kconfig | 4 + hw/input/meson.build | 2 + 4 files changed, 377 insertions(+) create mode 100644 include/hw/input/ft5336.h create mode 100644 hw/input/ft5336.c diff --git a/include/hw/input/ft5336.h b/include/hw/input/ft5336.h new file mode 100644 index 0000000000..7bef3f9efb --- /dev/null +++ b/include/hw/input/ft5336.h @@ -0,0 +1,14 @@ +/* + * FT5336 touch controller + * + * Copyright (c) 2022 Evgeny Ermakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_INPUT_FT5336_H +#define HW_INPUT_FT5336_H + +#define TYPE_FT5336 "ft5336" + +#endif diff --git a/hw/input/ft5336.c b/hw/input/ft5336.c new file mode 100644 index 0000000000..bacf79201a --- /dev/null +++ b/hw/input/ft5336.c @@ -0,0 +1,357 @@ +/* + * FT5336 touch controller + * + * Copyright (c) 2022 Evgeny Ermakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/input/ft5336.h" +#include "hw/i2c/i2c.h" +#include "hw/irq.h" +#include "migration/vmstate.h" +#include "qemu/module.h" +#include "qemu/log.h" +#include "qemu/timer.h" +#include "ui/input.h" +#include "qom/object.h" + +OBJECT_DECLARE_SIMPLE_TYPE(FT5336TouchState, FT5336) + +struct FT5336TouchState { + I2CSlave parent_obj; + + uint8_t i2c_cycle; + uint8_t reg; + + qemu_irq irq; + + int32_t abs_x; + int32_t abs_y; + uint16_t touch_x; + uint16_t touch_y; + bool touch_press; + + bool inte; +}; + +/* I2C Slave address of touchscreen FocalTech FT5336 */ +#define FT5336_I2C_SLAVE_ADDRESS 0x70 + +/* Maximum border values of the touchscreen pad */ +#define FT5336_MAX_WIDTH ((uint16_t)480) /* Touchsc= reen pad max width */ +#define FT5336_MAX_HEIGHT ((uint16_t)272) /* Touchsc= reen pad max height */ + +/* Max detectable simultaneous touches */ +#define FT5336_MAX_DETECTABLE_TOUCH 0x05 + + +enum { + FT5336_P_XH =3D 0x00, + FT5336_P_XL =3D 0x01, + FT5336_P_YH =3D 0x02, + FT5336_P_YL =3D 0x03, + /* Values Pn_XH and Pn_YH related */ +#define FT5336_TOUCH_EVT_FLAG_PRESS_DOWN 0x00 +#define FT5336_TOUCH_EVT_FLAG_LIFT_UP 0x01 +#define FT5336_TOUCH_EVT_FLAG_CONTACT 0x02 +#define FT5336_TOUCH_EVT_FLAG_NO_EVENT 0x03 + + FT5336_P_WEIGHT =3D 0x04, + /* Values Pn_WEIGHT related */ +#define FT5336_TOUCH_WEIGHT_MASK 0xFF +#define FT5336_TOUCH_WEIGHT_SHIFT 0x00 + + FT5336_P_MISC =3D 0x05 + /* Values related to FT5336_Pn_MISC_REG */ +#define FT5336_TOUCH_AREA_MASK (0x04 << 4)) +#define FT5336_TOUCH_AREA_SHIFT 0x04 +}; + +enum { + FT5336_R_MODE =3D 0x00, +#define FT5336_DEV_MODE_WORKING 0x00 +#define FT5336_DEV_MODE_FACTORY 0x04 + +#define FT5336_DEV_MODE_MASK 0x07 +#define FT5336_DEV_MODE_SHIFT 0x04 + + FT5336_R_GEST_ID =3D 0x01, +#define FT5336_GEST_ID_NO_GESTURE 0x00 +#define FT5336_GEST_ID_MOVE_UP 0x10 +#define FT5336_GEST_ID_MOVE_RIGHT 0x14 +#define FT5336_GEST_ID_MOVE_DOWN 0x18 +#define FT5336_GEST_ID_MOVE_LEFT 0x1C +#define FT5336_GEST_ID_SINGLE_CLICK 0x20 +#define FT5336_GEST_ID_DOUBLE_CLICK 0x22 +#define FT5336_GEST_ID_ROTATE_CLOCKWISE 0x28 +#define FT5336_GEST_ID_ROTATE_C_CLOCKWISE 0x29 +#define FT5336_GEST_ID_ZOOM_IN 0x40 +#define FT5336_GEST_ID_ZOOM_OUT 0x49 + + FT5336_R_STAT =3D 0x02, +#define FT5336_TD_STAT_MASK 0x0F +#define FT5336_TD_STAT_SHIFT 0x00 + + FT5336_R_P1_BASE =3D 0x03, + FT5336_R_P2_BASE =3D 0x09, + FT5336_R_P3_BASE =3D 0x0f, + FT5336_R_P4_BASE =3D 0x15, + FT5336_R_P5_BASE =3D 0x1b, + FT5336_R_P6_BASE =3D 0x21, + FT5336_R_P7_BASE =3D 0x27, + FT5336_R_P8_BASE =3D 0x2d, + FT5336_R_P9_BASE =3D 0x33, + FT5336_R_P10_BASE =3D 0x39, + +#define FT5336_TOUCH_EVT_FLAG_SHIFT 0x06 +#define FT5336_TOUCH_EVT_FLAG_MASK (3 << FT5336_TOUCH_EVT_FLAG_SH= IFT)) + +#define FT5336_TOUCH_POS_MSB_MASK 0x0F +#define FT5336_TOUCH_POS_MSB_SHIFT 0x00 + + /* Values Pn_XL and Pn_YL related */ +#define FT5336_TOUCH_POS_LSB_MASK 0xFF +#define FT5336_TOUCH_POS_LSB_SHIFT 0x00 + + FT5336_R_TH_GROUP =3D 0x80, + /* Values FT5336_TH_GROUP_REG : threshold related */ +#define FT5336_THRESHOLD_MASK 0xFF +#define FT5336_THRESHOLD_SHIFT 0x00 + + FT5336_R_TH_DIFF =3D 0x85, + + FT5336_R_CTRL =3D 0x86, + /* Values related to FT5336_CTRL_REG */ + + /* Will keep the Active mode when there is no touching */ +#define FT5336_CTRL_KEEP_ACTIVE_MODE 0x00 + + /* Switching from Active mode to Monitor mode automatically when there= is no touching */ +#define FT5336_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE 0x01 + FT5336_R_TIMEENTERMONITOR =3D 0x87, + FT5336_R_PERIODACTIVE =3D 0x88, + FT5336_R_PERIODMONITOR =3D 0x89, + FT5336_R_RADIAN_VALUE =3D 0x91, + FT5336_R_OFFSET_LEFT_RIGHT =3D 0x92, + FT5336_R_OFFSET_UP_DOWN =3D 0x93, + FT5336_R_DISTANCE_LEFT =3D 0x94, + FT5336_R_DISTANCE_UP_DOWN =3D 0x95, + FT5336_R_DISTANCE_ZOOM =3D 0x96, + + FT5336_R_LIB_VER_H =3D 0xa1, + FT5336_R_LIB_VER_L =3D 0xa2, + FT5336_R_CIPHER =3D 0xa3, + + FT5336_R_GMODE =3D 0xa4, +#define FT5336_G_MODE_INTERRUPT_MASK 0x03 +#define FT5336_G_MODE_INTERRUPT_SHIFT 0x00 + + /* Possible values of FT5336_GMODE_REG */ +#define FT5336_G_MODE_INTERRUPT_POLLING 0x00 +#define FT5336_G_MODE_INTERRUPT_TRIGGER 0x01 + + FT5336_R_PWR_MODE =3D 0xa5, + FT5336_R_FIRMID =3D 0xa6, + + FT5336_R_CHIP_ID =3D 0xa8, + /* Possible values of FT5336_CHIP_ID_REG */ +#define FT5336_ID_VALUE 0x51 + + FT5336_R_RELEASE_CODE_ID =3D 0xaf, + /* Release code version */ +#define FT5336_RELEASE_CODE_ID_REG 0xAF + + FT5336_R_STATE =3D 0xbc, +}; + + +static uint8_t ft5336_touch_read(FT5336TouchState *s, int reg, int byte) +{ + switch (reg) { + case FT5336_R_CHIP_ID: + return FT5336_ID_VALUE; + case FT5336_R_STAT: + return s->touch_press ? 1 : 0; + case FT5336_R_P1_BASE: + switch (byte) { + case FT5336_P_XH: return extract16(s->touch_x, 8, 8); + case FT5336_P_XL: return extract16(s->touch_x, 0, 8); + case FT5336_P_YH: return extract16(s->touch_y, 8, 8); + case FT5336_P_YL: return extract16(s->touch_y, 0, 8); + default: + return 0; + } + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: unknown register %02x\n", __func__, reg); + return 0; + } +} + +static void ft5336_touch_write(FT5336TouchState *s, int reg, int byte, uin= t8_t value) +{ + switch (reg) { + case FT5336_R_GMODE: + s->inte =3D value; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: unknown register %02x\n", __func__, reg); + break; + } +} + +static int ft5336_i2c_event(I2CSlave *i2c, enum i2c_event event) +{ + FT5336TouchState *s =3D FT5336(i2c); + + switch (event) { + case I2C_START_RECV: + case I2C_START_SEND: + s->i2c_cycle =3D 0; + break; + default: + break; + } + + return 0; +} + +static uint8_t ft5336_i2c_recv(I2CSlave *i2c) +{ + FT5336TouchState *s =3D FT5336(i2c); + + return ft5336_touch_read(s, s->reg, s->i2c_cycle++); +} + +static int ft5336_i2c_send(I2CSlave *i2c, uint8_t data) +{ + FT5336TouchState *s =3D FT5336(i2c); + + if (!s->i2c_cycle) { + s->reg =3D data; + } else { + ft5336_touch_write(s, s->reg, s->i2c_cycle - 1, data); + } + s->i2c_cycle++; + + return 0; +} + +static void ft5336_input_event(DeviceState *dev, QemuConsole *src, + InputEvent *evt) +{ + FT5336TouchState *s =3D FT5336(dev); + InputBtnEvent *btn =3D NULL; + InputMoveEvent *move =3D NULL; + + switch (evt->type) { + case INPUT_EVENT_KIND_BTN: + btn =3D evt->u.btn.data; + s->touch_press =3D btn->down; + break; + case INPUT_EVENT_KIND_ABS: + move =3D evt->u.rel.data; + if (move->axis =3D=3D INPUT_AXIS_X) { + s->abs_x =3D move->value; + } else if (move->axis =3D=3D INPUT_AXIS_Y) { + s->abs_y =3D move->value; + } + break; + default: + break; + } +} + +static void ft5336_input_sync(DeviceState *dev) +{ + FT5336TouchState *s =3D FT5336(dev);; + + s->touch_x =3D qemu_input_scale_axis(s->abs_x, + INPUT_EVENT_ABS_MIN, + INPUT_EVENT_ABS_MAX, 0, 1777); + s->touch_y =3D qemu_input_scale_axis(s->abs_y, + INPUT_EVENT_ABS_MIN, + INPUT_EVENT_ABS_MAX, 0, 1023); + + if (s->touch_press) { + if (s->inte) { + qemu_irq_pulse(s->irq); + } + } +} + +static QemuInputHandler ft5336_input_handler =3D { + .name =3D "QEMU FT5336-driven Touchscreen", + .mask =3D INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS, + .event =3D ft5336_input_event, + .sync =3D ft5336_input_sync +}; + +static void ft5336_touch_reset_enter(Object *obj, ResetType type) +{ + FT5336TouchState *s =3D FT5336(obj); + + s->inte =3D false; +} + +static void ft5336_realize(DeviceState *dev, Error **errp) +{ + FT5336TouchState *s =3D FT5336(dev); + qdev_init_gpio_out(dev, &s->irq, 1); + + qemu_input_handler_register((DeviceState *) s, &ft5336_input_handler); +} + +static int ft5336_touch_post_load(void *opaque, int version_id) +{ + /* FT5336TouchState *s =3D opaque; */ + + return 0; +} + +static const VMStateDescription vmstate_ft5336_touch =3D { + .name =3D TYPE_FT5336, + .version_id =3D 0, + .minimum_version_id =3D 0, + .post_load =3D ft5336_touch_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_I2C_SLAVE(parent_obj, FT5336TouchState), + VMSTATE_UINT8(i2c_cycle, FT5336TouchState), + VMSTATE_UINT8(reg, FT5336TouchState), + VMSTATE_END_OF_LIST() + } +}; + +static void ft5336_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + I2CSlaveClass *sc =3D I2C_SLAVE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + dc->realize =3D ft5336_realize; + dc->vmsd =3D &vmstate_ft5336_touch; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); + rc->phases.enter =3D ft5336_touch_reset_enter; + + sc->event =3D ft5336_i2c_event; + sc->recv =3D ft5336_i2c_recv; + sc->send =3D ft5336_i2c_send; +} + +static const TypeInfo ft5336_info =3D { + .name =3D TYPE_FT5336, + .parent =3D TYPE_I2C_SLAVE, + .instance_size =3D sizeof(FT5336TouchState), + .class_init =3D ft5336_class_init +}; + +static void ft5336_register_types(void) +{ + type_register_static(&ft5336_info); +} + +type_init(ft5336_register_types) diff --git a/hw/input/Kconfig b/hw/input/Kconfig index 55865bb386..73a6f67216 100644 --- a/hw/input/Kconfig +++ b/hw/input/Kconfig @@ -46,3 +46,7 @@ config TSC210X =20 config LASIPS2 select PS2 + +config FT5336 + bool + depends on I2C diff --git a/hw/input/meson.build b/hw/input/meson.build index 8deb011d4a..c892ecbeb7 100644 --- a/hw/input/meson.build +++ b/hw/input/meson.build @@ -16,3 +16,5 @@ softmmu_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: = files('vhost-user-input softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_keypad.c')) softmmu_ss.add(when: 'CONFIG_TSC210X', if_true: files('tsc210x.c')) softmmu_ss.add(when: 'CONFIG_LASIPS2', if_true: files('lasips2.c')) + +softmmu_ss.add(when: 'CONFIG_FT5336', if_true: files('ft5336.c')) --=20 2.38.1