[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: |
Philippe Mathieu-Daudé |
Subject: |
Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output |
Date: |
Sat, 12 Sep 2020 11:14:53 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0 |
On 9/12/20 11:02 AM, Philippe Mathieu-Daudé wrote:
> On 9/11/20 9:42 PM, Luc Michel wrote:
>> 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.
>
> "GpioPolarity not used in GPIO API": For now, but I expect it to be
> used there too. Maybe not soon, but some places could use it and
> become clearer.
>
>> 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.
>
> Very good point, thanks for your suggestion!
>
>>
>>> 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.
>
> I'll try, as this might postpone the need for the GpioPolarity enum
> (including its migration and the qapi enum visitors...).
After testing using a simple boolean, I think I'll keep the enum
as it makes the caller code easier to review:
s->led = led_create_simple(OBJECT(dev),
GPIO_POLARITY_ACTIVE_HIGH,
LED_COLOR_GREEN, name);
vs
s->led = led_create_simple(OBJECT(dev), true,
LED_COLOR_GREEN, name);
>
>>
>> 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;
>>>
>>
>
- [PATCH v5 0/7] hw/misc: Add LED device, Philippe Mathieu-Daudé, 2020/09/10
- [PATCH v5 1/7] hw/misc/led: Add a LED device, Philippe Mathieu-Daudé, 2020/09/10
- [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Philippe Mathieu-Daudé, 2020/09/10
- Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Richard Henderson, 2020/09/11
- Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Philippe Mathieu-Daudé, 2020/09/12
- Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Philippe Mathieu-Daudé, 2020/09/12
- Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Markus Armbruster, 2020/09/14
- Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Philippe Mathieu-Daudé, 2020/09/14
- Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Eduardo Habkost, 2020/09/14
- Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Philippe Mathieu-Daudé, 2020/09/14
- Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output, Philippe Mathieu-Daudé, 2020/09/14
[PATCH v5 3/7] hw/misc/led: Emit a trace event when LED intensity has changed, Philippe Mathieu-Daudé, 2020/09/10