10d75565fSKristian Kielhofner /* 20d75565fSKristian Kielhofner * LEDs driver for PCEngines WRAP 30d75565fSKristian Kielhofner * 40d75565fSKristian Kielhofner * Copyright (C) 2006 Kristian Kielhofner <kris@krisk.org> 50d75565fSKristian Kielhofner * 60d75565fSKristian Kielhofner * Based on leds-net48xx.c 70d75565fSKristian Kielhofner * 80d75565fSKristian Kielhofner * This program is free software; you can redistribute it and/or modify 90d75565fSKristian Kielhofner * it under the terms of the GNU General Public License version 2 as 100d75565fSKristian Kielhofner * published by the Free Software Foundation. 110d75565fSKristian Kielhofner */ 120d75565fSKristian Kielhofner 130d75565fSKristian Kielhofner #include <linux/kernel.h> 140d75565fSKristian Kielhofner #include <linux/init.h> 150d75565fSKristian Kielhofner #include <linux/platform_device.h> 160d75565fSKristian Kielhofner #include <linux/leds.h> 170d75565fSKristian Kielhofner #include <linux/err.h> 180d75565fSKristian Kielhofner #include <asm/io.h> 190d75565fSKristian Kielhofner #include <linux/scx200_gpio.h> 2054f4dedbSPaul Gortmaker #include <linux/module.h> 210d75565fSKristian Kielhofner 220d75565fSKristian Kielhofner #define DRVNAME "wrap-led" 23f5506a2fSMichael Loeffler #define WRAP_POWER_LED_GPIO 2 240d75565fSKristian Kielhofner #define WRAP_ERROR_LED_GPIO 3 250d75565fSKristian Kielhofner #define WRAP_EXTRA_LED_GPIO 18 260d75565fSKristian Kielhofner 270d75565fSKristian Kielhofner static struct platform_device *pdev; 280d75565fSKristian Kielhofner 29f5506a2fSMichael Loeffler static void wrap_power_led_set(struct led_classdev *led_cdev, 30f5506a2fSMichael Loeffler enum led_brightness value) 31f5506a2fSMichael Loeffler { 32f5506a2fSMichael Loeffler if (value) 33f5506a2fSMichael Loeffler scx200_gpio_set_low(WRAP_POWER_LED_GPIO); 34f5506a2fSMichael Loeffler else 35f5506a2fSMichael Loeffler scx200_gpio_set_high(WRAP_POWER_LED_GPIO); 36f5506a2fSMichael Loeffler } 37f5506a2fSMichael Loeffler 380d75565fSKristian Kielhofner static void wrap_error_led_set(struct led_classdev *led_cdev, 390d75565fSKristian Kielhofner enum led_brightness value) 400d75565fSKristian Kielhofner { 410d75565fSKristian Kielhofner if (value) 420d75565fSKristian Kielhofner scx200_gpio_set_low(WRAP_ERROR_LED_GPIO); 430d75565fSKristian Kielhofner else 440d75565fSKristian Kielhofner scx200_gpio_set_high(WRAP_ERROR_LED_GPIO); 450d75565fSKristian Kielhofner } 460d75565fSKristian Kielhofner 470d75565fSKristian Kielhofner static void wrap_extra_led_set(struct led_classdev *led_cdev, 480d75565fSKristian Kielhofner enum led_brightness value) 490d75565fSKristian Kielhofner { 500d75565fSKristian Kielhofner if (value) 510d75565fSKristian Kielhofner scx200_gpio_set_low(WRAP_EXTRA_LED_GPIO); 520d75565fSKristian Kielhofner else 530d75565fSKristian Kielhofner scx200_gpio_set_high(WRAP_EXTRA_LED_GPIO); 540d75565fSKristian Kielhofner } 550d75565fSKristian Kielhofner 56f5506a2fSMichael Loeffler static struct led_classdev wrap_power_led = { 57f5506a2fSMichael Loeffler .name = "wrap::power", 58f5506a2fSMichael Loeffler .brightness_set = wrap_power_led_set, 596af4f55cSSven Wegener .default_trigger = "default-on", 60859cb7f2SRichard Purdie .flags = LED_CORE_SUSPENDRESUME, 61f5506a2fSMichael Loeffler }; 62f5506a2fSMichael Loeffler 630d75565fSKristian Kielhofner static struct led_classdev wrap_error_led = { 646c152beeSRichard Purdie .name = "wrap::error", 650d75565fSKristian Kielhofner .brightness_set = wrap_error_led_set, 66859cb7f2SRichard Purdie .flags = LED_CORE_SUSPENDRESUME, 670d75565fSKristian Kielhofner }; 680d75565fSKristian Kielhofner 690d75565fSKristian Kielhofner static struct led_classdev wrap_extra_led = { 706c152beeSRichard Purdie .name = "wrap::extra", 710d75565fSKristian Kielhofner .brightness_set = wrap_extra_led_set, 72859cb7f2SRichard Purdie .flags = LED_CORE_SUSPENDRESUME, 730d75565fSKristian Kielhofner }; 740d75565fSKristian Kielhofner 750d75565fSKristian Kielhofner static int wrap_led_probe(struct platform_device *pdev) 760d75565fSKristian Kielhofner { 770d75565fSKristian Kielhofner int ret; 780d75565fSKristian Kielhofner 79f5506a2fSMichael Loeffler ret = led_classdev_register(&pdev->dev, &wrap_power_led); 80f5506a2fSMichael Loeffler if (ret < 0) 81f5506a2fSMichael Loeffler return ret; 82f5506a2fSMichael Loeffler 830d75565fSKristian Kielhofner ret = led_classdev_register(&pdev->dev, &wrap_error_led); 84f5506a2fSMichael Loeffler if (ret < 0) 85f5506a2fSMichael Loeffler goto err1; 86f5506a2fSMichael Loeffler 870d75565fSKristian Kielhofner ret = led_classdev_register(&pdev->dev, &wrap_extra_led); 880d75565fSKristian Kielhofner if (ret < 0) 89f5506a2fSMichael Loeffler goto err2; 90f5506a2fSMichael Loeffler 91f5506a2fSMichael Loeffler return ret; 92f5506a2fSMichael Loeffler 93f5506a2fSMichael Loeffler err2: 940d75565fSKristian Kielhofner led_classdev_unregister(&wrap_error_led); 95f5506a2fSMichael Loeffler err1: 96f5506a2fSMichael Loeffler led_classdev_unregister(&wrap_power_led); 97f5506a2fSMichael Loeffler 980d75565fSKristian Kielhofner return ret; 990d75565fSKristian Kielhofner } 1000d75565fSKristian Kielhofner 1010d75565fSKristian Kielhofner static int wrap_led_remove(struct platform_device *pdev) 1020d75565fSKristian Kielhofner { 103f5506a2fSMichael Loeffler led_classdev_unregister(&wrap_power_led); 1040d75565fSKristian Kielhofner led_classdev_unregister(&wrap_error_led); 1050d75565fSKristian Kielhofner led_classdev_unregister(&wrap_extra_led); 1060d75565fSKristian Kielhofner return 0; 1070d75565fSKristian Kielhofner } 1080d75565fSKristian Kielhofner 1090d75565fSKristian Kielhofner static struct platform_driver wrap_led_driver = { 1100d75565fSKristian Kielhofner .probe = wrap_led_probe, 1110d75565fSKristian Kielhofner .remove = wrap_led_remove, 1120d75565fSKristian Kielhofner .driver = { 1130d75565fSKristian Kielhofner .name = DRVNAME, 1140d75565fSKristian Kielhofner .owner = THIS_MODULE, 1150d75565fSKristian Kielhofner }, 1160d75565fSKristian Kielhofner }; 1170d75565fSKristian Kielhofner 1180d75565fSKristian Kielhofner static int __init wrap_led_init(void) 1190d75565fSKristian Kielhofner { 1200d75565fSKristian Kielhofner int ret; 1210d75565fSKristian Kielhofner 1220d75565fSKristian Kielhofner if (!scx200_gpio_present()) { 1230d75565fSKristian Kielhofner ret = -ENODEV; 1240d75565fSKristian Kielhofner goto out; 1250d75565fSKristian Kielhofner } 1260d75565fSKristian Kielhofner 1270d75565fSKristian Kielhofner ret = platform_driver_register(&wrap_led_driver); 1280d75565fSKristian Kielhofner if (ret < 0) 1290d75565fSKristian Kielhofner goto out; 1300d75565fSKristian Kielhofner 1310d75565fSKristian Kielhofner pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); 1320d75565fSKristian Kielhofner if (IS_ERR(pdev)) { 1330d75565fSKristian Kielhofner ret = PTR_ERR(pdev); 1340d75565fSKristian Kielhofner platform_driver_unregister(&wrap_led_driver); 1350d75565fSKristian Kielhofner goto out; 1360d75565fSKristian Kielhofner } 1370d75565fSKristian Kielhofner 1380d75565fSKristian Kielhofner out: 1390d75565fSKristian Kielhofner return ret; 1400d75565fSKristian Kielhofner } 1410d75565fSKristian Kielhofner 1420d75565fSKristian Kielhofner static void __exit wrap_led_exit(void) 1430d75565fSKristian Kielhofner { 1440d75565fSKristian Kielhofner platform_device_unregister(pdev); 1450d75565fSKristian Kielhofner platform_driver_unregister(&wrap_led_driver); 1460d75565fSKristian Kielhofner } 1470d75565fSKristian Kielhofner 1480d75565fSKristian Kielhofner module_init(wrap_led_init); 1490d75565fSKristian Kielhofner module_exit(wrap_led_exit); 1500d75565fSKristian Kielhofner 1510d75565fSKristian Kielhofner MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>"); 1520d75565fSKristian Kielhofner MODULE_DESCRIPTION("PCEngines WRAP LED driver"); 1530d75565fSKristian Kielhofner MODULE_LICENSE("GPL"); 1540d75565fSKristian Kielhofner 155