qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output


From: Luc Michel
Subject: Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output
Date: Fri, 11 Sep 2020 21:42:05 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0

Hi Phil,

On 9/10/20 10:54 PM, Philippe Mathieu-Daudé wrote:
Some devices expose GPIO lines.

Add a GPIO qdev input to our LED device, so we can
connect a GPIO output using qdev_connect_gpio_out().

When used with GPIOs, the intensity can only be either
minium or maximum. This depends of the polarity of the
GPIO (which can be inverted).
Declare the GpioPolarity type to model the polarity.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
  include/hw/misc/led.h  |  8 ++++++++
  include/hw/qdev-core.h |  8 ++++++++
  hw/misc/led.c          | 17 ++++++++++++++++-
  3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/include/hw/misc/led.h b/include/hw/misc/led.h
index f5afaa34bfb..71c9b8c59bf 100644
--- a/include/hw/misc/led.h
+++ b/include/hw/misc/led.h
@@ -38,10 +38,16 @@ typedef struct LEDState {
      /* Public */
uint8_t intensity_percent;
+    qemu_irq irq;
/* Properties */
      char *description;
      char *color;
+    /*
+     * When used with GPIO, the intensity at reset is related
+     * to the GPIO polarity.
+     */
+    bool inverted_polarity;
  } LEDState;
/**
@@ -71,6 +77,7 @@ void led_set_state(LEDState *s, bool is_emitting);
  /**
   * led_create_simple: Create and realize a LED device
   * @parentobj: the parent object
+ * @gpio_polarity: GPIO polarity
   * @color: color of the LED
   * @description: description of the LED (optional)
   *
@@ -78,6 +85,7 @@ void led_set_state(LEDState *s, bool is_emitting);
   * drop the reference to it (the device is realized).
   */
  LEDState *led_create_simple(Object *parentobj,
+                            GpioPolarity gpio_polarity,
                              LEDColor color,
                              const char *description);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index ea3f73a282d..846354736a5 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -424,6 +424,14 @@ void qdev_simple_device_unplug_cb(HotplugHandler 
*hotplug_dev,
  void qdev_machine_creation_done(void);
  bool qdev_machine_modified(void);
+/**
+ * GpioPolarity: Polarity of a GPIO line
+ */
+typedef enum {
+    GPIO_POLARITY_ACTIVE_LOW,
+    GPIO_POLARITY_ACTIVE_HIGH
+} GpioPolarity;
+
  /**
   * qdev_get_gpio_in: Get one of a device's anonymous input GPIO lines
   * @dev: Device whose GPIO we want
diff --git a/hw/misc/led.c b/hw/misc/led.c
index 89acd9acbb7..3ef4f5e0469 100644
--- a/hw/misc/led.c
+++ b/hw/misc/led.c
@@ -10,6 +10,7 @@
  #include "migration/vmstate.h"
  #include "hw/qdev-properties.h"
  #include "hw/misc/led.h"
+#include "hw/irq.h"
  #include "trace.h"
#define LED_INTENSITY_PERCENT_MAX 100
@@ -53,11 +54,19 @@ void led_set_state(LEDState *s, bool is_emitting)
      led_set_intensity(s, is_emitting ? LED_INTENSITY_PERCENT_MAX : 0);
  }
+static void led_set_state_gpio_handler(void *opaque, int line, int new_state)
+{
+    LEDState *s = LED(opaque);
+
+    assert(line == 0);
+    led_set_state(s, !!new_state != s->inverted_polarity);
+}
+
  static void led_reset(DeviceState *dev)
  {
      LEDState *s = LED(dev);
- led_set_state(s, false);
+    led_set_state(s, s->inverted_polarity);
  }
static const VMStateDescription vmstate_led = {
@@ -84,11 +93,14 @@ static void led_realize(DeviceState *dev, Error **errp)
      if (s->description == NULL) {
          s->description = g_strdup("n/a");
      }
+
+    qdev_init_gpio_in(DEVICE(s), led_set_state_gpio_handler, 1);
  }
static Property led_properties[] = {
      DEFINE_PROP_STRING("color", LEDState, color),
      DEFINE_PROP_STRING("description", LEDState, description),
+    DEFINE_PROP_BOOL("polarity-inverted", LEDState, inverted_polarity, false),
I was wondering, since the GpioPolarity type you introduce is not used in the GPIO API, and since you use a boolean property here. Wouldn't it be clearer is you name this property "active-low"? Because "polarity-inverted" doesn't tell what the polarity is in the first place. Moreover since this property only affects the LED GPIO, and not the LED API (led_set_state), I think you can even name it "gpio-active-low" to make this clear.

      DEFINE_PROP_END_OF_LIST(),
  };
@@ -119,6 +131,7 @@ static void led_register_types(void)
  type_init(led_register_types)
LEDState *led_create_simple(Object *parentobj,
+                            GpioPolarity gpio_polarity,
You could go with a boolean here also and name the parameter gpio_active_low, but I don't have a strong opinion on this.

So with or without those modifications:
Reviewed-by: Luc Michel <luc.michel@greensocs.com>

                              LEDColor color,
                              const char *description)
  {
@@ -126,6 +139,8 @@ LEDState *led_create_simple(Object *parentobj,
      DeviceState *dev;
dev = qdev_new(TYPE_LED);
+    qdev_prop_set_bit(dev, "polarity-inverted",
+                      gpio_polarity == GPIO_POLARITY_ACTIVE_LOW);
      qdev_prop_set_string(dev, "color", led_color_name[color]);
      if (!description) {
          static unsigned undescribed_led_id;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]