diff mbox series

[RFC,4/6] hw/arm/npcm7xx: gpio: Add GPIO transmitter

Message ID 20211216015417.1234812-5-komlodi@google.com (mailing list archive)
State New, archived
Headers show
Series Introduce GPIO transmitter and connect to NPCM7xx | expand

Commit Message

Joe Komlodi Dec. 16, 2021, 1:54 a.m. UTC
This adds the GPIO transmitter to the NPCM7xx GPIO controller and
transmits packets any time the pin state changes.

Signed-off-by: Joe Komlodi <komlodi@google.com>
---
 hw/arm/Kconfig                 |  1 +
 hw/arm/npcm7xx.c               |  7 +++++++
 hw/gpio/npcm7xx_gpio.c         | 14 ++++++++++++++
 include/hw/arm/npcm7xx.h       |  2 ++
 include/hw/gpio/npcm7xx_gpio.h |  3 +++
 5 files changed, 27 insertions(+)
diff mbox series

Patch

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index ac11493667..046e277db8 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -399,6 +399,7 @@  config NPCM7XX
     select UNIMP
     select PCA954X
+    select GOOGLE_GPIO_TRANSMITTER
 
 config FSL_IMX25
     bool
     select IMX
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 6a48a9a6d4..b3a65e5298 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -433,6 +433,9 @@  static void npcm7xx_init(Object *obj)
         object_initialize_child(obj, "gpio[*]", &s->gpio[i], TYPE_NPCM7XX_GPIO);
     }
 
+    object_initialize_child(obj, "gpiotx", &s->gpiotx,
+                            TYPE_GOOGLE_GPIO_TRANSMITTER);
+
     for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
         object_initialize_child(obj, "smbus[*]", &s->smbus[i],
                                 TYPE_NPCM7XX_SMBUS);
@@ -590,11 +593,15 @@  static void npcm7xx_realize(DeviceState *dev, Error **errp)
     sysbus_realize(SYS_BUS_DEVICE(&s->rng), &error_abort);
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->rng), 0, NPCM7XX_RNG_BA);
 
+    sysbus_realize(SYS_BUS_DEVICE(&s->gpiotx), &error_abort);
+
     /* GPIO modules. Cannot fail. */
     QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_gpio) != ARRAY_SIZE(s->gpio));
     for (i = 0; i < ARRAY_SIZE(s->gpio); i++) {
         Object *obj = OBJECT(&s->gpio[i]);
 
+        object_property_set_link(obj, "gpio-tx", OBJECT(&s->gpiotx),
+                                 &error_abort);
         object_property_set_uint(obj, "controller-num", i, &error_abort);
         object_property_set_uint(obj, "reset-pullup",
                                  npcm7xx_gpio[i].reset_pu, &error_abort);
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
index db62c4ed00..900436f901 100644
--- a/hw/gpio/meson.build
+++ b/hw/gpio/meson.build
@@ -7,6 +7,7 @@  softmmu_ss.add(when: 'CONFIG_ZAURUS', if_true: files('zaurus.c'))
 
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpio.c'))
 softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_gpio.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('google_gpio_transmitter.c'))
 softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_gpio.c'))
 softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_gpio.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c'))
diff --git a/hw/gpio/npcm7xx_gpio.c b/hw/gpio/npcm7xx_gpio.c
index 5075f61b3b..0d683903a2 100644
--- a/hw/gpio/npcm7xx_gpio.c
+++ b/hw/gpio/npcm7xx_gpio.c
@@ -65,6 +65,16 @@  enum NPCM7xxGPIORegister {
 #define NPCM7XX_GPIO_LOCK_MAGIC1 (0xc0defa73)
 #define NPCM7XX_GPIO_LOCK_MAGIC2 (0xc0de1248)
 
+static void npcm7xx_gpio_tx_state(NPCM7xxGPIOState *s)
+{
+    uint32_t state = s->regs[NPCM7XX_GPIO_DOUT] | s->regs[NPCM7XX_GPIO_DIN];
+
+    /* Only TX if we have a transmitter */
+    if (s->txs) {
+        google_gpio_tx_transmit(s->txs, s->controller_num, state);
+    }
+}
+
 static void npcm7xx_gpio_update_events(NPCM7xxGPIOState *s, uint32_t din_diff)
 {
     uint32_t din_new = s->regs[NPCM7XX_GPIO_DIN];
@@ -147,6 +157,7 @@  static void npcm7xx_gpio_update_pins(NPCM7xxGPIOState *s, uint32_t diff)
 
     /* See if any new events triggered because of all this. */
     npcm7xx_gpio_update_events(s, din_old ^ s->regs[NPCM7XX_GPIO_DIN]);
+    npcm7xx_gpio_tx_state(s);
 }
 
 static bool npcm7xx_gpio_is_locked(NPCM7xxGPIOState *s)
@@ -387,6 +398,9 @@  static const VMStateDescription vmstate_npcm7xx_gpio = {
 };
 
 static Property npcm7xx_gpio_properties[] = {
+    /* Pointer to the GPIO state transmitter */
+    DEFINE_PROP_LINK("gpio-tx", NPCM7xxGPIOState, txs,
+                     TYPE_GOOGLE_GPIO_TRANSMITTER, GoogleGPIOTXState *),
     /* The GPIO controller number (out of 8) */
     DEFINE_PROP_UINT8("controller-num", NPCM7xxGPIOState, controller_num, 0),
     /* Bit n set => pin n has pullup enabled by default. */
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 106cfb55bf..a52650010f 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -21,6 +21,7 @@ 
 #include "hw/core/split-irq.h"
 #include "hw/cpu/a9mpcore.h"
 #include "hw/gpio/npcm7xx_gpio.h"
+#include "hw/gpio/google_gpio_transmitter.h"
 #include "hw/i2c/npcm7xx_smbus.h"
 #include "hw/mem/npcm7xx_mc.h"
 #include "hw/misc/npcm7xx_clk.h"
@@ -99,6 +100,7 @@  typedef struct NPCM7xxState {
     NPCM7xxMCState      mc;
     NPCM7xxRNGState     rng;
     NPCM7xxGPIOState    gpio[8];
+    GoogleGPIOTXState   gpiotx;
     NPCM7xxSMBusState   smbus[16];
     EHCISysBusState     ehci;
     OHCISysBusState     ohci;
diff --git a/include/hw/gpio/npcm7xx_gpio.h b/include/hw/gpio/npcm7xx_gpio.h
index b065bba1c5..69c1004a6c 100644
--- a/include/hw/gpio/npcm7xx_gpio.h
+++ b/include/hw/gpio/npcm7xx_gpio.h
@@ -17,6 +17,7 @@ 
 
 #include "exec/memory.h"
 #include "hw/sysbus.h"
+#include "hw/gpio/google_gpio_transmitter.h"
 
 /* Number of pins managed by each controller. */
 #define NPCM7XX_GPIO_NR_PINS (32)
@@ -30,6 +31,8 @@ 
 typedef struct NPCM7xxGPIOState {
     SysBusDevice parent;
 
+    GoogleGPIOTXState *txs;
+
     /* Properties to be defined by the SoC */
     uint32_t reset_pu;
     uint32_t reset_pd;