0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/slab.h>
0013 #include <linux/leds.h>
0014 #include <linux/io.h>
0015 #include <linux/module.h>
0016
0017
0018 struct ot200_led {
0019 struct led_classdev cdev;
0020 const char *name;
0021 unsigned long port;
0022 u8 mask;
0023 };
0024
0025
0026
0027
0028
0029
0030 static struct ot200_led leds[] = {
0031 {
0032 .name = "led_run",
0033 .port = 0x5a,
0034 .mask = BIT(0),
0035 },
0036 {
0037 .name = "led_init",
0038 .port = 0x5a,
0039 .mask = BIT(1),
0040 },
0041 {
0042 .name = "led_err",
0043 .port = 0x5a,
0044 .mask = BIT(2),
0045 },
0046 {
0047 .name = "led_1",
0048 .port = 0x49,
0049 .mask = BIT(6),
0050 },
0051 {
0052 .name = "led_2",
0053 .port = 0x49,
0054 .mask = BIT(5),
0055 },
0056 {
0057 .name = "led_3",
0058 .port = 0x49,
0059 .mask = BIT(4),
0060 },
0061 {
0062 .name = "led_4",
0063 .port = 0x49,
0064 .mask = BIT(3),
0065 },
0066 {
0067 .name = "led_5",
0068 .port = 0x49,
0069 .mask = BIT(2),
0070 },
0071 {
0072 .name = "led_6",
0073 .port = 0x49,
0074 .mask = BIT(1),
0075 },
0076 {
0077 .name = "led_7",
0078 .port = 0x49,
0079 .mask = BIT(0),
0080 }
0081 };
0082
0083 static DEFINE_SPINLOCK(value_lock);
0084
0085
0086
0087
0088
0089 static u8 leds_back;
0090 static u8 leds_front;
0091
0092 static void ot200_led_brightness_set(struct led_classdev *led_cdev,
0093 enum led_brightness value)
0094 {
0095 struct ot200_led *led = container_of(led_cdev, struct ot200_led, cdev);
0096 u8 *val;
0097 unsigned long flags;
0098
0099 spin_lock_irqsave(&value_lock, flags);
0100
0101 if (led->port == 0x49)
0102 val = &leds_front;
0103 else if (led->port == 0x5a)
0104 val = &leds_back;
0105 else
0106 BUG();
0107
0108 if (value == LED_OFF)
0109 *val &= ~led->mask;
0110 else
0111 *val |= led->mask;
0112
0113 outb(*val, led->port);
0114 spin_unlock_irqrestore(&value_lock, flags);
0115 }
0116
0117 static int ot200_led_probe(struct platform_device *pdev)
0118 {
0119 int i;
0120 int ret;
0121
0122 for (i = 0; i < ARRAY_SIZE(leds); i++) {
0123
0124 leds[i].cdev.name = leds[i].name;
0125 leds[i].cdev.brightness_set = ot200_led_brightness_set;
0126
0127 ret = devm_led_classdev_register(&pdev->dev, &leds[i].cdev);
0128 if (ret < 0)
0129 return ret;
0130 }
0131
0132 leds_front = 0;
0133 leds_back = BIT(1);
0134 outb(leds_front, 0x49);
0135 outb(leds_back, 0x5a);
0136
0137 return 0;
0138 }
0139
0140 static struct platform_driver ot200_led_driver = {
0141 .probe = ot200_led_probe,
0142 .driver = {
0143 .name = "leds-ot200",
0144 },
0145 };
0146
0147 module_platform_driver(ot200_led_driver);
0148
0149 MODULE_AUTHOR("Sebastian A. Siewior <bigeasy@linutronix.de>");
0150 MODULE_DESCRIPTION("ot200 LED driver");
0151 MODULE_LICENSE("GPL");
0152 MODULE_ALIAS("platform:leds-ot200");