diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:27:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:27:49 +0000 |
commit | ace9429bb58fd418f0c81d4c2835699bddf6bde6 (patch) | |
tree | b2d64bc10158fdd5497876388cd68142ca374ed3 /drivers/leds/simple/simatic-ipc-leds-gpio-core.c | |
parent | Initial commit. (diff) | |
download | linux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.tar.xz linux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.zip |
Adding upstream version 6.6.15.upstream/6.6.15
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/leds/simple/simatic-ipc-leds-gpio-core.c')
-rw-r--r-- | drivers/leds/simple/simatic-ipc-leds-gpio-core.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/drivers/leds/simple/simatic-ipc-leds-gpio-core.c b/drivers/leds/simple/simatic-ipc-leds-gpio-core.c new file mode 100644 index 0000000000..c552ea73ed --- /dev/null +++ b/drivers/leds/simple/simatic-ipc-leds-gpio-core.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Siemens SIMATIC IPC driver for GPIO based LEDs + * + * Copyright (c) Siemens AG, 2023 + * + * Author: + * Henning Schild <henning.schild@siemens.com> + */ + +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> +#include <linux/leds.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/platform_data/x86/simatic-ipc-base.h> + +#include "simatic-ipc-leds-gpio.h" + +static struct platform_device *simatic_leds_pdev; + +static const struct gpio_led simatic_ipc_gpio_leds[] = { + { .name = "red:" LED_FUNCTION_STATUS "-1" }, + { .name = "green:" LED_FUNCTION_STATUS "-1" }, + { .name = "red:" LED_FUNCTION_STATUS "-2" }, + { .name = "green:" LED_FUNCTION_STATUS "-2" }, + { .name = "red:" LED_FUNCTION_STATUS "-3" }, + { .name = "green:" LED_FUNCTION_STATUS "-3" }, +}; + +static const struct gpio_led_platform_data simatic_ipc_gpio_leds_pdata = { + .num_leds = ARRAY_SIZE(simatic_ipc_gpio_leds), + .leds = simatic_ipc_gpio_leds, +}; + +int simatic_ipc_leds_gpio_remove(struct platform_device *pdev, + struct gpiod_lookup_table *table, + struct gpiod_lookup_table *table_extra) +{ + gpiod_remove_lookup_table(table); + gpiod_remove_lookup_table(table_extra); + platform_device_unregister(simatic_leds_pdev); + + return 0; +} +EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_remove); + +int simatic_ipc_leds_gpio_probe(struct platform_device *pdev, + struct gpiod_lookup_table *table, + struct gpiod_lookup_table *table_extra) +{ + const struct simatic_ipc_platform *plat = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct gpio_desc *gpiod; + int err; + + switch (plat->devmode) { + case SIMATIC_IPC_DEVICE_127E: + case SIMATIC_IPC_DEVICE_227G: + case SIMATIC_IPC_DEVICE_BX_21A: + break; + default: + return -ENODEV; + } + + gpiod_add_lookup_table(table); + simatic_leds_pdev = platform_device_register_resndata(NULL, + "leds-gpio", PLATFORM_DEVID_NONE, NULL, 0, + &simatic_ipc_gpio_leds_pdata, + sizeof(simatic_ipc_gpio_leds_pdata)); + if (IS_ERR(simatic_leds_pdev)) { + err = PTR_ERR(simatic_leds_pdev); + goto out; + } + + if (!table_extra) + return 0; + + table_extra->dev_id = dev_name(dev); + gpiod_add_lookup_table(table_extra); + + /* PM_BIOS_BOOT_N */ + gpiod = gpiod_get_index(dev, NULL, 6, GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + err = PTR_ERR(gpiod); + goto out; + } + gpiod_put(gpiod); + + /* PM_WDT_OUT */ + gpiod = gpiod_get_index(dev, NULL, 7, GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + err = PTR_ERR(gpiod); + goto out; + } + gpiod_put(gpiod); + + return 0; +out: + simatic_ipc_leds_gpio_remove(pdev, table, table_extra); + + return err; +} +EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_probe); + +MODULE_LICENSE("GPL v2"); +MODULE_SOFTDEP("pre: platform:leds-gpio"); +MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>"); |