From nobody Thu Nov 14 18:08:15 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=1708703663; cv=none; d=zohomail.com; s=zohoarc; b=m85d34PvQ30epRuqNGO9vGUdnACHcizwvOHgAoAg3ZXzMq94D2pZfK4araeR5FvMuTE7Gxl38b6aHJzBeennRw0a96z6N4fVP15aNryGJl73erTxN77qE6ayxw6Waa5wmUlLNQ+UNbXDI0ANMTGgPKbbREvGtek0Ry1lZGED6rw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1708703663; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=q36jhjRJi9//Rq92Z4CXsjy5rE5fVHQHoeYIuEypDgo=; b=PfH+ng/Ge62+R3hPQSnhSNV58tkxcKnu2FB3fq2jtIJdzdrdlQznuLQ5wuzaxSLqxyi0PNeVrsdCmrL4TWvuPR6vmN/VHWbqRpVTe8pcNmTESViua3IU9EFf04a0yuz/F5mx0tasd0wRESCPId4N0/VI0Gy5YRSHAdWz/gEHuPc= 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 1708703663091744.3792989078945; Fri, 23 Feb 2024 07:54:23 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rdXre-0006Qf-Ap; Fri, 23 Feb 2024 10:53:30 -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 1rdXj7-0005eL-RB; Fri, 23 Feb 2024 10:44:41 -0500 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rdXj6-0006NR-6v; Fri, 23 Feb 2024 10:44:41 -0500 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1dc5d0162bcso8022355ad.0; Fri, 23 Feb 2024 07:44:39 -0800 (PST) Received: from wheely.local0.net (220-235-194-103.tpgi.com.au. [220.235.194.103]) by smtp.gmail.com with ESMTPSA id h18-20020a170902f2d200b001d913992d8csm11808208plc.242.2024.02.23.07.44.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Feb 2024 07:44:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1708703078; x=1709307878; darn=nongnu.org; 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=q36jhjRJi9//Rq92Z4CXsjy5rE5fVHQHoeYIuEypDgo=; b=hDSbfliXSt6twpr+oKyBA6Bft5OBb1qzYnvgllrFakQ6h7/ZetibfwaDEOh4GEGj/g frC59idmidP+EcXNnUUBKLCpKReSsRJ8zjTY6AF1htZpRtxrN4ulFJr64SFB0vYDs87x L4YjPvNTqSqrOd4QuQ4171pLPou2b/0gXVwtRWtRvVvWZYC4Vvj+r1T8MPk+ZR+XlSls mpxxzlYLu6lKTMMZik9xDH50lMR/WtXp7amxDLn/UCluuGsEsIaZfOwDtxEmdt9rS4pq 1lW3zpnfM+tH4vm1GiLvqAa9o6QBjEC95ezekY/CkMnu+Tj0FKsowTKdel3Jcvk4+5iO O5QQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708703078; x=1709307878; 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=q36jhjRJi9//Rq92Z4CXsjy5rE5fVHQHoeYIuEypDgo=; b=sqR+XLLD5g/TYfFjZ1/D08Jp1ZPZCTQBVAKJk1Nrzf9WZdbZn8hWqAp6e4QjSM9gGb aJTC5Dqba7wq4DpPE543bNiu9f4PclcZIPyF/wqJD96cSEkKvZI/vh40FvCahjedP3Pl Cz51BUtkISV7787oCzB6WXl5mH5TUZRu0SZ1zDz/NK9w5IqrUFoSasUpuqMF/vVR2wVE EdmZMc1ATI9IdB3G1hPwsO3OAisjOuTcvR0H2wyvxFHWSvfFyHUKXkuV1ZzaLvdtWZL1 hgq2nKtJ2RLjyRETkOnn/7In24+VPkVSajxTJunqh0i8Q4Ry0n3UpJ2L1KOFA80qOpG7 wnkA== X-Forwarded-Encrypted: i=1; AJvYcCUdZZTN3LU/yFlNgEajyNupuR/Ssi69mLumEcw1E2+tuMFzvxfDC7J+VLZYpG2AakfxouywDp6mccO4jqESJMWLEgEz X-Gm-Message-State: AOJu0Yy4348znwkkpLlOpuo2yfLpJQdRHqVlXDZSc/csOjXx00xyzg28 Fjy7AbburE8geXS4HvuD5Vn5Yj2XD9NVMeLwKkQpaaSiIJJ6QFTotbm1NpFq X-Google-Smtp-Source: AGHT+IGWuaQySoRuhdqboM25THBmhk2DvZUvnOxionIfcT/LCuxMuLynBhHC+3oxNzj3WdBMNUID+Q== X-Received: by 2002:a17:902:f681:b0:1db:4213:41e8 with SMTP id l1-20020a170902f68100b001db421341e8mr111796plg.69.1708703078369; Fri, 23 Feb 2024 07:44:38 -0800 (PST) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Daniel Henrique Barboza , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Harsh Prateek Bora , Glenn Miles , Andrew Jeffery Subject: [PULL 22/47] misc/pca9552: Let external devices set pca9552 inputs Date: Sat, 24 Feb 2024 01:41:41 +1000 Message-ID: <20240223154211.1001692-23-npiggin@gmail.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240223154211.1001692-1-npiggin@gmail.com> References: <20240223154211.1001692-1-npiggin@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=2607:f8b0:4864:20::62c; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham 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: 1708703664638100010 Content-Type: text/plain; charset="utf-8" From: Glenn Miles Allow external devices to drive pca9552 input pins by adding input GPIO's to the model. This allows a device to connect its output GPIO's to the pca9552 input GPIO's. In order for an external device to set the state of a pca9552 pin, the pin must first be configured for high impedance (LED is off). If the pca9552 pin is configured to drive the pin low (LED is on), then external input will be ignored. Here is a table describing the logical state of a pca9552 pin given the state being driven by the pca9552 and an external device: PCA9552 Configured State | Hi-Z | Low | ------+------+-----+ External Hi-Z | Hi | Low | Device ------+------+-----+ State Low | Low | Low | ------+------+-----+ Reviewed-by: Andrew Jeffery Signed-off-by: Glenn Miles Signed-off-by: Nicholas Piggin --- hw/misc/pca9552.c | 50 +++++++++++++++++++++++++++++++++------ include/hw/misc/pca9552.h | 3 ++- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c index f00a149d61..2ae13af35e 100644 --- a/hw/misc/pca9552.c +++ b/hw/misc/pca9552.c @@ -44,6 +44,8 @@ DECLARE_CLASS_CHECKERS(PCA955xClass, PCA955X, #define PCA9552_LED_OFF 0x1 #define PCA9552_LED_PWM0 0x2 #define PCA9552_LED_PWM1 0x3 +#define PCA9552_PIN_LOW 0x0 +#define PCA9552_PIN_HIZ 0x1 =20 static const char *led_state[] =3D {"on", "off", "pwm0", "pwm1"}; =20 @@ -110,22 +112,27 @@ static void pca955x_update_pin_input(PCA955xState *s) =20 for (i =3D 0; i < k->pin_count; i++) { uint8_t input_reg =3D PCA9552_INPUT0 + (i / 8); - uint8_t input_shift =3D (i % 8); + uint8_t bit_mask =3D 1 << (i % 8); uint8_t config =3D pca955x_pin_get_config(s, i); + uint8_t old_value =3D s->regs[input_reg] & bit_mask; + uint8_t new_value; =20 switch (config) { case PCA9552_LED_ON: /* Pin is set to 0V to turn on LED */ - qemu_set_irq(s->gpio[i], 0); - s->regs[input_reg] &=3D ~(1 << input_shift); + s->regs[input_reg] &=3D ~bit_mask; break; case PCA9552_LED_OFF: /* * Pin is set to Hi-Z to turn off LED and - * pullup sets it to a logical 1. + * pullup sets it to a logical 1 unless + * external device drives it low. */ - qemu_set_irq(s->gpio[i], 1); - s->regs[input_reg] |=3D 1 << input_shift; + if (s->ext_state[i] =3D=3D PCA9552_PIN_LOW) { + s->regs[input_reg] &=3D ~bit_mask; + } else { + s->regs[input_reg] |=3D bit_mask; + } break; case PCA9552_LED_PWM0: case PCA9552_LED_PWM1: @@ -133,6 +140,12 @@ static void pca955x_update_pin_input(PCA955xState *s) default: break; } + + /* update irq state only if pin state changed */ + new_value =3D s->regs[input_reg] & bit_mask; + if (new_value !=3D old_value) { + qemu_set_irq(s->gpio_out[i], !!new_value); + } } } =20 @@ -340,6 +353,7 @@ static const VMStateDescription pca9552_vmstate =3D { VMSTATE_UINT8(len, PCA955xState), VMSTATE_UINT8(pointer, PCA955xState), VMSTATE_UINT8_ARRAY(regs, PCA955xState, PCA955X_NR_REGS), + VMSTATE_UINT8_ARRAY(ext_state, PCA955xState, PCA955X_PIN_COUNT_MAX= ), VMSTATE_I2C_SLAVE(i2c, PCA955xState), VMSTATE_END_OF_LIST() } @@ -358,6 +372,7 @@ static void pca9552_reset(DeviceState *dev) s->regs[PCA9552_LS2] =3D 0x55; s->regs[PCA9552_LS3] =3D 0x55; =20 + memset(s->ext_state, PCA9552_PIN_HIZ, PCA955X_PIN_COUNT_MAX); pca955x_update_pin_input(s); =20 s->pointer =3D 0xFF; @@ -380,6 +395,26 @@ static void pca955x_initfn(Object *obj) } } =20 +static void pca955x_set_ext_state(PCA955xState *s, int pin, int level) +{ + if (s->ext_state[pin] !=3D level) { + uint16_t pins_status =3D pca955x_pins_get_status(s); + s->ext_state[pin] =3D level; + pca955x_update_pin_input(s); + pca955x_display_pins_status(s, pins_status); + } +} + +static void pca955x_gpio_in_handler(void *opaque, int pin, int level) +{ + + PCA955xState *s =3D PCA955X(opaque); + PCA955xClass *k =3D PCA955X_GET_CLASS(s); + + assert((pin >=3D 0) && (pin < k->pin_count)); + pca955x_set_ext_state(s, pin, level); +} + static void pca955x_realize(DeviceState *dev, Error **errp) { PCA955xClass *k =3D PCA955X_GET_CLASS(dev); @@ -389,7 +424,8 @@ static void pca955x_realize(DeviceState *dev, Error **e= rrp) s->description =3D g_strdup("pca-unspecified"); } =20 - qdev_init_gpio_out(dev, s->gpio, k->pin_count); + qdev_init_gpio_out(dev, s->gpio_out, k->pin_count); + qdev_init_gpio_in(dev, pca955x_gpio_in_handler, k->pin_count); } =20 static Property pca955x_properties[] =3D { diff --git a/include/hw/misc/pca9552.h b/include/hw/misc/pca9552.h index b6f4e264fe..c36525f0c3 100644 --- a/include/hw/misc/pca9552.h +++ b/include/hw/misc/pca9552.h @@ -30,7 +30,8 @@ struct PCA955xState { uint8_t pointer; =20 uint8_t regs[PCA955X_NR_REGS]; - qemu_irq gpio[PCA955X_PIN_COUNT_MAX]; + qemu_irq gpio_out[PCA955X_PIN_COUNT_MAX]; + uint8_t ext_state[PCA955X_PIN_COUNT_MAX]; char *description; /* For debugging purpose only */ }; =20 --=20 2.42.0