1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * LED Driver for SGI Octane machines |
4 | */ |
5 | |
6 | #include <asm/io.h> |
7 | #include <linux/module.h> |
8 | #include <linux/kernel.h> |
9 | #include <linux/platform_device.h> |
10 | #include <linux/leds.h> |
11 | |
12 | #define IP30_LED_SYSTEM 0 |
13 | #define IP30_LED_FAULT 1 |
14 | |
15 | struct ip30_led { |
16 | struct led_classdev cdev; |
17 | u32 __iomem *reg; |
18 | }; |
19 | |
20 | static void ip30led_set(struct led_classdev *led_cdev, |
21 | enum led_brightness value) |
22 | { |
23 | struct ip30_led *led = container_of(led_cdev, struct ip30_led, cdev); |
24 | |
25 | writel(val: value, addr: led->reg); |
26 | } |
27 | |
28 | static int ip30led_create(struct platform_device *pdev, int num) |
29 | { |
30 | struct ip30_led *data; |
31 | |
32 | data = devm_kzalloc(dev: &pdev->dev, size: sizeof(*data), GFP_KERNEL); |
33 | if (!data) |
34 | return -ENOMEM; |
35 | |
36 | data->reg = devm_platform_ioremap_resource(pdev, index: num); |
37 | if (IS_ERR(ptr: data->reg)) |
38 | return PTR_ERR(ptr: data->reg); |
39 | |
40 | switch (num) { |
41 | case IP30_LED_SYSTEM: |
42 | data->cdev.name = "white:power" ; |
43 | break; |
44 | case IP30_LED_FAULT: |
45 | data->cdev.name = "red:fault" ; |
46 | break; |
47 | default: |
48 | return -EINVAL; |
49 | } |
50 | |
51 | data->cdev.brightness = readl(addr: data->reg); |
52 | data->cdev.max_brightness = 1; |
53 | data->cdev.brightness_set = ip30led_set; |
54 | |
55 | return devm_led_classdev_register(parent: &pdev->dev, led_cdev: &data->cdev); |
56 | } |
57 | |
58 | static int ip30led_probe(struct platform_device *pdev) |
59 | { |
60 | int ret; |
61 | |
62 | ret = ip30led_create(pdev, IP30_LED_SYSTEM); |
63 | if (ret < 0) |
64 | return ret; |
65 | |
66 | return ip30led_create(pdev, IP30_LED_FAULT); |
67 | } |
68 | |
69 | static struct platform_driver ip30led_driver = { |
70 | .probe = ip30led_probe, |
71 | .driver = { |
72 | .name = "ip30-leds" , |
73 | }, |
74 | }; |
75 | |
76 | module_platform_driver(ip30led_driver); |
77 | |
78 | MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>" ); |
79 | MODULE_DESCRIPTION("SGI Octane LED driver" ); |
80 | MODULE_LICENSE("GPL" ); |
81 | MODULE_ALIAS("platform:ip30-leds" ); |
82 | |