From: Chris Packham <chris.packham@alliedtelesis.co.nz> To: andy@kernel.org, geert@linux-m68k.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, andrew@lunn.ch, gregory.clement@bootlin.com, sebastian.hesselbarth@gmail.com, ojeda@kernel.org, tzimmermann@suse.de, javierm@redhat.com, robin@protonic.nl, lee@kernel.org, pavel@ucw.cz Cc: devicetree@vger.kernel.org, linux-leds@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Chris Packham <chris.packham@alliedtelesis.co.nz> Subject: [PATCH v2 1/4] auxdisplay: Add 7 segment LED display driver Date: Wed, 28 Feb 2024 10:22:41 +1300 [thread overview] Message-ID: <20240227212244.262710-2-chris.packham@alliedtelesis.co.nz> (raw) In-Reply-To: <20240227212244.262710-1-chris.packham@alliedtelesis.co.nz> Add a driver for a 7 segment LED display. At the moment only one character is supported but it should be possible to expand this to support more characters and/or 14 segment displays in the future. Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz> --- Notes: Changes in v2: - Rebased on top of auxdisplay/for-next dropping unnecessary code for 7 segment maps. - Update for new linedisp_register() API - Include headers based on actual usage - Allow building as module - Use compatible = "generic-gpio-7seg" to keep checkpatch.pl happy drivers/auxdisplay/Kconfig | 10 +++ drivers/auxdisplay/Makefile | 1 + drivers/auxdisplay/seg-led.c | 119 +++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 drivers/auxdisplay/seg-led.c diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index d4be0a3695ce..52a245ca0c8d 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -211,6 +211,16 @@ config ARM_CHARLCD line and the Linux version on the second line, but that's still useful. +config SEG_LED + tristate "Generic 7 segment LED display" + select LINEDISP + help + This driver supports a generic 7 segment LED display made up + of GPIO pins connected to the individual segments. + + This driver can also be built as a module. If so, the module + will be called seg-led. + menuconfig PARPORT_PANEL tristate "Parallel port LCD/Keypad Panel support" depends on PARPORT diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile index a725010ca651..744e354318ae 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_PARPORT_PANEL) += panel.o obj-$(CONFIG_LCD2S) += lcd2s.o obj-$(CONFIG_LINEDISP) += line-display.o obj-$(CONFIG_MAX6959) += max6959.o +obj-$(CONFIG_SEG_LED) += seg-led.o diff --git a/drivers/auxdisplay/seg-led.c b/drivers/auxdisplay/seg-led.c new file mode 100644 index 000000000000..7bb304fcaa6e --- /dev/null +++ b/drivers/auxdisplay/seg-led.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for a 7 segment LED display + * + * The GPIOs are wired to the 7 segments in a clockwise fashion starting from + * the top. + * + * -a- + * | | + * f b + * | | + * -g- + * | | + * e c + * | | + * -d- + * + * The decimal point LED present on some devices is currently not + * supported. + * + * Copyright (C) Allied Telesis Labs + */ + +#include <linux/container_of.h> +#include <linux/errno.h> +#include <linux/gpio/consumer.h> +#include <linux/kernel.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/types.h> +#include <linux/workqueue.h> + +#include "line-display.h" + +struct seg_led_priv { + struct gpio_descs *segment_gpios; + struct delayed_work work; + struct linedisp linedisp; +}; + +static void seg_led_update(struct work_struct *work) +{ + struct seg_led_priv *priv = container_of(work, struct seg_led_priv, work.work); + struct linedisp_map *map = priv->linedisp.map; + DECLARE_BITMAP(values, 8); + + values[0] = map_to_seg7(&map->map.seg7, priv->linedisp.buf[0]); + + gpiod_set_array_value_cansleep(priv->segment_gpios->ndescs, priv->segment_gpios->desc, + priv->segment_gpios->info, values); +} + +static int seg_led_linedisp_get_map_type(struct linedisp *linedisp) +{ + return LINEDISP_MAP_SEG7; +} + +static void seg_led_linedisp_update(struct linedisp *linedisp) +{ + struct seg_led_priv *priv = container_of(linedisp, struct seg_led_priv, linedisp); + + schedule_delayed_work(&priv->work, 0); +} + +static const struct linedisp_ops seg_led_linedisp_ops = { + .get_map_type = seg_led_linedisp_get_map_type, + .update = seg_led_linedisp_update, +}; + +static const struct of_device_id seg_led_of_match[] = { + { .compatible = "generic-gpio-7seg"}, + {} +}; +MODULE_DEVICE_TABLE(of, seg_led_of_match); + +static int seg_led_probe(struct platform_device *pdev) +{ + struct seg_led_priv *priv; + struct device *dev = &pdev->dev; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + priv->segment_gpios = devm_gpiod_get_array(dev, "segment", GPIOD_OUT_LOW); + if (IS_ERR(priv->segment_gpios)) + return PTR_ERR(priv->segment_gpios); + + INIT_DELAYED_WORK(&priv->work, seg_led_update); + + return linedisp_register(&priv->linedisp, dev, 1, &seg_led_linedisp_ops); +} + +static int seg_led_remove(struct platform_device *pdev) +{ + struct seg_led_priv *priv = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&priv->work); + linedisp_unregister(&priv->linedisp); + + return 0; +} + +static struct platform_driver seg_led_driver = { + .probe = seg_led_probe, + .remove = seg_led_remove, + .driver = { + .name = "seg-led", + .of_match_table = seg_led_of_match, + }, +}; +module_platform_driver(seg_led_driver); + +MODULE_AUTHOR("Chris Packham <chris.packham@alliedtelesis.co.nz>"); +MODULE_DESCRIPTION("7 segment LED driver"); +MODULE_LICENSE("GPL"); -- 2.43.2
WARNING: multiple messages have this Message-ID (diff)
From: Chris Packham <chris.packham@alliedtelesis.co.nz> To: andy@kernel.org, geert@linux-m68k.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, andrew@lunn.ch, gregory.clement@bootlin.com, sebastian.hesselbarth@gmail.com, ojeda@kernel.org, tzimmermann@suse.de, javierm@redhat.com, robin@protonic.nl, lee@kernel.org, pavel@ucw.cz Cc: devicetree@vger.kernel.org, linux-leds@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Chris Packham <chris.packham@alliedtelesis.co.nz> Subject: [PATCH v2 1/4] auxdisplay: Add 7 segment LED display driver Date: Wed, 28 Feb 2024 10:22:41 +1300 [thread overview] Message-ID: <20240227212244.262710-2-chris.packham@alliedtelesis.co.nz> (raw) In-Reply-To: <20240227212244.262710-1-chris.packham@alliedtelesis.co.nz> Add a driver for a 7 segment LED display. At the moment only one character is supported but it should be possible to expand this to support more characters and/or 14 segment displays in the future. Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz> --- Notes: Changes in v2: - Rebased on top of auxdisplay/for-next dropping unnecessary code for 7 segment maps. - Update for new linedisp_register() API - Include headers based on actual usage - Allow building as module - Use compatible = "generic-gpio-7seg" to keep checkpatch.pl happy drivers/auxdisplay/Kconfig | 10 +++ drivers/auxdisplay/Makefile | 1 + drivers/auxdisplay/seg-led.c | 119 +++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 drivers/auxdisplay/seg-led.c diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index d4be0a3695ce..52a245ca0c8d 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -211,6 +211,16 @@ config ARM_CHARLCD line and the Linux version on the second line, but that's still useful. +config SEG_LED + tristate "Generic 7 segment LED display" + select LINEDISP + help + This driver supports a generic 7 segment LED display made up + of GPIO pins connected to the individual segments. + + This driver can also be built as a module. If so, the module + will be called seg-led. + menuconfig PARPORT_PANEL tristate "Parallel port LCD/Keypad Panel support" depends on PARPORT diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile index a725010ca651..744e354318ae 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_PARPORT_PANEL) += panel.o obj-$(CONFIG_LCD2S) += lcd2s.o obj-$(CONFIG_LINEDISP) += line-display.o obj-$(CONFIG_MAX6959) += max6959.o +obj-$(CONFIG_SEG_LED) += seg-led.o diff --git a/drivers/auxdisplay/seg-led.c b/drivers/auxdisplay/seg-led.c new file mode 100644 index 000000000000..7bb304fcaa6e --- /dev/null +++ b/drivers/auxdisplay/seg-led.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for a 7 segment LED display + * + * The GPIOs are wired to the 7 segments in a clockwise fashion starting from + * the top. + * + * -a- + * | | + * f b + * | | + * -g- + * | | + * e c + * | | + * -d- + * + * The decimal point LED present on some devices is currently not + * supported. + * + * Copyright (C) Allied Telesis Labs + */ + +#include <linux/container_of.h> +#include <linux/errno.h> +#include <linux/gpio/consumer.h> +#include <linux/kernel.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/types.h> +#include <linux/workqueue.h> + +#include "line-display.h" + +struct seg_led_priv { + struct gpio_descs *segment_gpios; + struct delayed_work work; + struct linedisp linedisp; +}; + +static void seg_led_update(struct work_struct *work) +{ + struct seg_led_priv *priv = container_of(work, struct seg_led_priv, work.work); + struct linedisp_map *map = priv->linedisp.map; + DECLARE_BITMAP(values, 8); + + values[0] = map_to_seg7(&map->map.seg7, priv->linedisp.buf[0]); + + gpiod_set_array_value_cansleep(priv->segment_gpios->ndescs, priv->segment_gpios->desc, + priv->segment_gpios->info, values); +} + +static int seg_led_linedisp_get_map_type(struct linedisp *linedisp) +{ + return LINEDISP_MAP_SEG7; +} + +static void seg_led_linedisp_update(struct linedisp *linedisp) +{ + struct seg_led_priv *priv = container_of(linedisp, struct seg_led_priv, linedisp); + + schedule_delayed_work(&priv->work, 0); +} + +static const struct linedisp_ops seg_led_linedisp_ops = { + .get_map_type = seg_led_linedisp_get_map_type, + .update = seg_led_linedisp_update, +}; + +static const struct of_device_id seg_led_of_match[] = { + { .compatible = "generic-gpio-7seg"}, + {} +}; +MODULE_DEVICE_TABLE(of, seg_led_of_match); + +static int seg_led_probe(struct platform_device *pdev) +{ + struct seg_led_priv *priv; + struct device *dev = &pdev->dev; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + priv->segment_gpios = devm_gpiod_get_array(dev, "segment", GPIOD_OUT_LOW); + if (IS_ERR(priv->segment_gpios)) + return PTR_ERR(priv->segment_gpios); + + INIT_DELAYED_WORK(&priv->work, seg_led_update); + + return linedisp_register(&priv->linedisp, dev, 1, &seg_led_linedisp_ops); +} + +static int seg_led_remove(struct platform_device *pdev) +{ + struct seg_led_priv *priv = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&priv->work); + linedisp_unregister(&priv->linedisp); + + return 0; +} + +static struct platform_driver seg_led_driver = { + .probe = seg_led_probe, + .remove = seg_led_remove, + .driver = { + .name = "seg-led", + .of_match_table = seg_led_of_match, + }, +}; +module_platform_driver(seg_led_driver); + +MODULE_AUTHOR("Chris Packham <chris.packham@alliedtelesis.co.nz>"); +MODULE_DESCRIPTION("7 segment LED driver"); +MODULE_LICENSE("GPL"); -- 2.43.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2024-02-27 21:22 UTC|newest] Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-02-27 21:22 [PATCH v2 0/4] auxdisplay: 7 segment LED display Chris Packham 2024-02-27 21:22 ` Chris Packham 2024-02-27 21:22 ` Chris Packham [this message] 2024-02-27 21:22 ` [PATCH v2 1/4] auxdisplay: Add 7 segment LED display driver Chris Packham 2024-02-27 22:13 ` Randy Dunlap 2024-02-27 22:13 ` Randy Dunlap 2024-02-27 23:56 ` Andy Shevchenko 2024-02-27 23:56 ` Andy Shevchenko 2024-02-27 21:22 ` [PATCH v2 2/4] dt-bindings: auxdisplay: Add bindings for generic 7 segment LED Chris Packham 2024-02-27 21:22 ` Chris Packham 2024-02-27 22:19 ` Rob Herring 2024-02-27 22:19 ` Rob Herring 2024-02-28 0:03 ` Andy Shevchenko 2024-02-28 0:03 ` Andy Shevchenko 2024-02-28 1:53 ` Chris Packham 2024-02-28 1:53 ` Chris Packham 2024-02-28 17:22 ` Andy Shevchenko 2024-02-28 17:22 ` Andy Shevchenko 2024-02-28 14:04 ` Rob Herring 2024-02-28 14:04 ` Rob Herring 2024-02-28 14:57 ` Andy Shevchenko 2024-02-28 14:57 ` Andy Shevchenko 2024-02-29 9:23 ` Geert Uytterhoeven 2024-02-29 9:23 ` Geert Uytterhoeven 2024-02-29 10:42 ` Andy Shevchenko 2024-02-29 10:42 ` Andy Shevchenko 2024-02-28 20:01 ` Chris Packham 2024-02-28 20:01 ` Chris Packham 2024-02-29 9:24 ` Geert Uytterhoeven 2024-02-29 9:24 ` Geert Uytterhoeven 2024-02-29 10:44 ` andy 2024-02-29 10:44 ` andy 2024-02-27 21:22 ` [PATCH v2 3/4] ARM: dts: marvell: Add 7 segment LED display on x530 Chris Packham 2024-02-27 21:22 ` Chris Packham 2024-02-28 0:12 ` Andy Shevchenko 2024-02-28 0:12 ` Andy Shevchenko 2024-02-27 21:22 ` [PATCH v2 4/4] ARM: dts: marvell: Indicate USB activity " Chris Packham 2024-02-27 21:22 ` Chris Packham 2024-02-28 0:09 ` Andy Shevchenko 2024-02-28 0:09 ` Andy Shevchenko 2024-02-28 1:11 ` Chris Packham 2024-02-28 1:11 ` Chris Packham 2024-02-28 0:05 ` [PATCH v2 0/4] auxdisplay: 7 segment LED display Andy Shevchenko 2024-02-28 0:05 ` Andy Shevchenko 2024-02-28 0:25 ` Chris Packham 2024-02-28 0:25 ` Chris Packham 2024-02-28 18:45 ` Andy Shevchenko 2024-02-28 18:45 ` Andy Shevchenko
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240227212244.262710-2-chris.packham@alliedtelesis.co.nz \ --to=chris.packham@alliedtelesis.co.nz \ --cc=andrew@lunn.ch \ --cc=andy@kernel.org \ --cc=conor+dt@kernel.org \ --cc=devicetree@vger.kernel.org \ --cc=geert@linux-m68k.org \ --cc=gregory.clement@bootlin.com \ --cc=javierm@redhat.com \ --cc=krzysztof.kozlowski+dt@linaro.org \ --cc=lee@kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-leds@vger.kernel.org \ --cc=ojeda@kernel.org \ --cc=pavel@ucw.cz \ --cc=robh+dt@kernel.org \ --cc=robin@protonic.nl \ --cc=sebastian.hesselbarth@gmail.com \ --cc=tzimmermann@suse.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.