simatic-ipc-leds-gpio-core.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. #include <linux/gpio/machine.h>
  11. #include <linux/gpio/consumer.h>
  12. #include <linux/leds.h>
  13. #include <linux/module.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/platform_data/x86/simatic-ipc-base.h>
  16. #include "simatic-ipc-leds-gpio.h"
  17. static struct platform_device *simatic_leds_pdev;
  18. static const struct gpio_led simatic_ipc_gpio_leds[] = {
  19. { .name = "red:" LED_FUNCTION_STATUS "-1" },
  20. { .name = "green:" LED_FUNCTION_STATUS "-1" },
  21. { .name = "red:" LED_FUNCTION_STATUS "-2" },
  22. { .name = "green:" LED_FUNCTION_STATUS "-2" },
  23. { .name = "red:" LED_FUNCTION_STATUS "-3" },
  24. { .name = "green:" LED_FUNCTION_STATUS "-3" },
  25. };
  26. static const struct gpio_led_platform_data simatic_ipc_gpio_leds_pdata = {
  27. .num_leds = ARRAY_SIZE(simatic_ipc_gpio_leds),
  28. .leds = simatic_ipc_gpio_leds,
  29. };
  30. void simatic_ipc_leds_gpio_remove(struct platform_device *pdev,
  31. struct gpiod_lookup_table *table,
  32. struct gpiod_lookup_table *table_extra)
  33. {
  34. gpiod_remove_lookup_table(table);
  35. gpiod_remove_lookup_table(table_extra);
  36. platform_device_unregister(simatic_leds_pdev);
  37. }
  38. EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_remove);
  39. int simatic_ipc_leds_gpio_probe(struct platform_device *pdev,
  40. struct gpiod_lookup_table *table,
  41. struct gpiod_lookup_table *table_extra)
  42. {
  43. const struct simatic_ipc_platform *plat = pdev->dev.platform_data;
  44. struct device *dev = &pdev->dev;
  45. struct gpio_desc *gpiod;
  46. int err;
  47. switch (plat->devmode) {
  48. case SIMATIC_IPC_DEVICE_127E:
  49. case SIMATIC_IPC_DEVICE_227G:
  50. case SIMATIC_IPC_DEVICE_BX_21A:
  51. case SIMATIC_IPC_DEVICE_BX_59A:
  52. break;
  53. default:
  54. return -ENODEV;
  55. }
  56. gpiod_add_lookup_table(table);
  57. simatic_leds_pdev = platform_device_register_resndata(NULL,
  58. "leds-gpio", PLATFORM_DEVID_NONE, NULL, 0,
  59. &simatic_ipc_gpio_leds_pdata,
  60. sizeof(simatic_ipc_gpio_leds_pdata));
  61. if (IS_ERR(simatic_leds_pdev)) {
  62. err = PTR_ERR(simatic_leds_pdev);
  63. goto out;
  64. }
  65. if (!table_extra)
  66. return 0;
  67. table_extra->dev_id = dev_name(dev);
  68. gpiod_add_lookup_table(table_extra);
  69. /* PM_BIOS_BOOT_N */
  70. gpiod = gpiod_get_index(dev, NULL, 6, GPIOD_OUT_LOW);
  71. if (IS_ERR(gpiod)) {
  72. err = PTR_ERR(gpiod);
  73. goto out;
  74. }
  75. gpiod_put(gpiod);
  76. /* PM_WDT_OUT */
  77. gpiod = gpiod_get_index(dev, NULL, 7, GPIOD_OUT_LOW);
  78. if (IS_ERR(gpiod)) {
  79. err = PTR_ERR(gpiod);
  80. goto out;
  81. }
  82. gpiod_put(gpiod);
  83. return 0;
  84. out:
  85. simatic_ipc_leds_gpio_remove(pdev, table, table_extra);
  86. return err;
  87. }
  88. EXPORT_SYMBOL_GPL(simatic_ipc_leds_gpio_probe);
  89. MODULE_DESCRIPTION("Siemens SIMATIC IPC core driver for GPIO based LEDs");
  90. MODULE_LICENSE("GPL v2");
  91. MODULE_SOFTDEP("pre: platform:leds-gpio");
  92. MODULE_AUTHOR("Henning Schild <henning.schild@siemens.com>");