1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Siemens SIMATIC IPC driver for GPIO based LEDs
4 *
5 * Copyright (c) Siemens AG, 2023
6 *
7 * Author:
8 * Henning Schild <henning.schild@siemens.com>
9 */
10
11 #include <linux/gpio/machine.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/leds.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/platform_data/x86/simatic-ipc-base.h>
17
18 #include "simatic-ipc-leds-gpio.h"
19
20 struct simatic_ipc_led_tables {
21 struct gpiod_lookup_table *led_lookup_table;
22 struct gpiod_lookup_table *led_lookup_table_extra;
23 };
24
25 static struct gpiod_lookup_table simatic_ipc_led_gpio_table_227g = {
26 .dev_id = "leds-gpio",
27 .table = {
28 GPIO_LOOKUP_IDX("gpio-f7188x-2", 0, NULL, 0, GPIO_ACTIVE_LOW),
29 GPIO_LOOKUP_IDX("gpio-f7188x-2", 1, NULL, 1, GPIO_ACTIVE_LOW),
30 GPIO_LOOKUP_IDX("gpio-f7188x-2", 2, NULL, 2, GPIO_ACTIVE_LOW),
31 GPIO_LOOKUP_IDX("gpio-f7188x-2", 3, NULL, 3, GPIO_ACTIVE_LOW),
32 GPIO_LOOKUP_IDX("gpio-f7188x-2", 4, NULL, 4, GPIO_ACTIVE_LOW),
33 GPIO_LOOKUP_IDX("gpio-f7188x-2", 5, NULL, 5, GPIO_ACTIVE_LOW),
34 {} /* Terminating entry */
35 },
36 };
37
38 static struct gpiod_lookup_table simatic_ipc_led_gpio_table_extra_227g = {
39 .dev_id = NULL, /* Filled during initialization */
40 .table = {
41 GPIO_LOOKUP_IDX("gpio-f7188x-3", 6, NULL, 6, GPIO_ACTIVE_HIGH),
42 GPIO_LOOKUP_IDX("gpio-f7188x-3", 7, NULL, 7, GPIO_ACTIVE_HIGH),
43 {} /* Terminating entry */
44 },
45 };
46
47 static struct gpiod_lookup_table simatic_ipc_led_gpio_table_bx_59a = {
48 .dev_id = "leds-gpio",
49 .table = {
50 GPIO_LOOKUP_IDX("gpio-f7188x-2", 0, NULL, 0, GPIO_ACTIVE_LOW),
51 GPIO_LOOKUP_IDX("gpio-f7188x-2", 3, NULL, 1, GPIO_ACTIVE_LOW),
52 GPIO_LOOKUP_IDX("gpio-f7188x-5", 3, NULL, 2, GPIO_ACTIVE_LOW),
53 GPIO_LOOKUP_IDX("gpio-f7188x-5", 2, NULL, 3, GPIO_ACTIVE_LOW),
54 GPIO_LOOKUP_IDX("gpio-f7188x-7", 7, NULL, 4, GPIO_ACTIVE_LOW),
55 GPIO_LOOKUP_IDX("gpio-f7188x-7", 4, NULL, 5, GPIO_ACTIVE_LOW),
56 {} /* Terminating entry */
57 }
58 };
59
simatic_ipc_leds_gpio_f7188x_probe(struct platform_device * pdev)60 static int simatic_ipc_leds_gpio_f7188x_probe(struct platform_device *pdev)
61 {
62 const struct simatic_ipc_platform *plat = dev_get_platdata(&pdev->dev);
63 struct simatic_ipc_led_tables *led_tables;
64
65 led_tables = devm_kzalloc(&pdev->dev, sizeof(*led_tables), GFP_KERNEL);
66 if (!led_tables)
67 return -ENOMEM;
68
69 switch (plat->devmode) {
70 case SIMATIC_IPC_DEVICE_227G:
71 led_tables->led_lookup_table = &simatic_ipc_led_gpio_table_227g;
72 led_tables->led_lookup_table_extra = &simatic_ipc_led_gpio_table_extra_227g;
73 break;
74 case SIMATIC_IPC_DEVICE_BX_59A:
75 led_tables->led_lookup_table = &simatic_ipc_led_gpio_table_bx_59a;
76 break;
77 default:
78 return -ENODEV;
79 }
80
81 platform_set_drvdata(pdev, led_tables);
82 return simatic_ipc_leds_gpio_probe(pdev, led_tables->led_lookup_table,
83 led_tables->led_lookup_table_extra);
84 }
85
simatic_ipc_leds_gpio_f7188x_remove(struct platform_device * pdev)86 static void simatic_ipc_leds_gpio_f7188x_remove(struct platform_device *pdev)
87 {
88 struct simatic_ipc_led_tables *led_tables = platform_get_drvdata(pdev);
89
90 simatic_ipc_leds_gpio_remove(pdev, led_tables->led_lookup_table,
91 led_tables->led_lookup_table_extra);
92 }
93
94 static struct platform_driver simatic_ipc_led_gpio_driver = {
95 .probe = simatic_ipc_leds_gpio_f7188x_probe,
96 .remove = simatic_ipc_leds_gpio_f7188x_remove,
97 .driver = {
98 .name = KBUILD_MODNAME,
99 },
100 };
101 module_platform_driver(simatic_ipc_led_gpio_driver);
102
103 MODULE_DESCRIPTION("LED driver for Siemens Simatic IPCs based on Nuvoton GPIO");
104 MODULE_LICENSE("GPL v2");
105 MODULE_ALIAS("platform:" KBUILD_MODNAME);
106 MODULE_SOFTDEP("pre: simatic-ipc-leds-gpio-core gpio_f7188x");
107 MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>");
108