1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * LEDs driver for PCEngines WRAP 4 * 5 * Copyright (C) 2006 Kristian Kielhofner <kris@krisk.org> 6 * 7 * Based on leds-net48xx.c 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/init.h> 12 #include <linux/platform_device.h> 13 #include <linux/leds.h> 14 #include <linux/err.h> 15 #include <linux/io.h> 16 #include <linux/scx200_gpio.h> 17 #include <linux/module.h> 18 19 #define DRVNAME "wrap-led" 20 #define WRAP_POWER_LED_GPIO 2 21 #define WRAP_ERROR_LED_GPIO 3 22 #define WRAP_EXTRA_LED_GPIO 18 23 24 static struct platform_device *pdev; 25 26 static void wrap_power_led_set(struct led_classdev *led_cdev, 27 enum led_brightness value) 28 { 29 if (value) 30 scx200_gpio_set_low(WRAP_POWER_LED_GPIO); 31 else 32 scx200_gpio_set_high(WRAP_POWER_LED_GPIO); 33 } 34 35 static void wrap_error_led_set(struct led_classdev *led_cdev, 36 enum led_brightness value) 37 { 38 if (value) 39 scx200_gpio_set_low(WRAP_ERROR_LED_GPIO); 40 else 41 scx200_gpio_set_high(WRAP_ERROR_LED_GPIO); 42 } 43 44 static void wrap_extra_led_set(struct led_classdev *led_cdev, 45 enum led_brightness value) 46 { 47 if (value) 48 scx200_gpio_set_low(WRAP_EXTRA_LED_GPIO); 49 else 50 scx200_gpio_set_high(WRAP_EXTRA_LED_GPIO); 51 } 52 53 static struct led_classdev wrap_power_led = { 54 .name = "wrap::power", 55 .brightness_set = wrap_power_led_set, 56 .default_trigger = "default-on", 57 .flags = LED_CORE_SUSPENDRESUME, 58 }; 59 60 static struct led_classdev wrap_error_led = { 61 .name = "wrap::error", 62 .brightness_set = wrap_error_led_set, 63 .flags = LED_CORE_SUSPENDRESUME, 64 }; 65 66 static struct led_classdev wrap_extra_led = { 67 .name = "wrap::extra", 68 .brightness_set = wrap_extra_led_set, 69 .flags = LED_CORE_SUSPENDRESUME, 70 }; 71 72 static int wrap_led_probe(struct platform_device *pdev) 73 { 74 int ret; 75 76 ret = devm_led_classdev_register(&pdev->dev, &wrap_power_led); 77 if (ret < 0) 78 return ret; 79 80 ret = devm_led_classdev_register(&pdev->dev, &wrap_error_led); 81 if (ret < 0) 82 return ret; 83 84 return devm_led_classdev_register(&pdev->dev, &wrap_extra_led); 85 } 86 87 static struct platform_driver wrap_led_driver = { 88 .probe = wrap_led_probe, 89 .driver = { 90 .name = DRVNAME, 91 }, 92 }; 93 94 static int __init wrap_led_init(void) 95 { 96 int ret; 97 98 if (!scx200_gpio_present()) { 99 ret = -ENODEV; 100 goto out; 101 } 102 103 ret = platform_driver_register(&wrap_led_driver); 104 if (ret < 0) 105 goto out; 106 107 pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); 108 if (IS_ERR(pdev)) { 109 ret = PTR_ERR(pdev); 110 platform_driver_unregister(&wrap_led_driver); 111 goto out; 112 } 113 114 out: 115 return ret; 116 } 117 118 static void __exit wrap_led_exit(void) 119 { 120 platform_device_unregister(pdev); 121 platform_driver_unregister(&wrap_led_driver); 122 } 123 124 module_init(wrap_led_init); 125 module_exit(wrap_led_exit); 126 127 MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>"); 128 MODULE_DESCRIPTION("PCEngines WRAP LED driver"); 129 MODULE_LICENSE("GPL"); 130 131