xref: /linux/drivers/leds/simple/simatic-ipc-leds-gpio-f7188x.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
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 
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 
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