diff options
author | Ben Dooks <ben-linux@fluff.org> | 2006-04-11 01:54:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-11 09:18:40 -0400 |
commit | 54bdc470100b9d8ffd349a3ebe23013c25affddf (patch) | |
tree | 5cc56a985c77c662bdc1c9239de9563b11237e15 /drivers/leds | |
parent | aa7271076ae6547d7f370ad7e91ef86fdb318f17 (diff) |
[PATCH] S3C24XX GPIO LED support
GPIO LED support for Samsung S3C24XX SoC series processors.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Acked-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/Kconfig | 7 | ||||
-rw-r--r-- | drivers/leds/Makefile | 1 | ||||
-rw-r--r-- | drivers/leds/leds-s3c24xx.c | 163 |
3 files changed, 171 insertions, 0 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 2c4f20b7f021..88565becb877 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -59,6 +59,13 @@ config LEDS_TOSA | |||
59 | This option enables support for the LEDs on Sharp Zaurus | 59 | This option enables support for the LEDs on Sharp Zaurus |
60 | SL-6000 series. | 60 | SL-6000 series. |
61 | 61 | ||
62 | config LEDS_S3C24XX | ||
63 | tristate "LED Support for Samsung S3C24XX GPIO LEDs" | ||
64 | depends on LEDS_CLASS && ARCH_S3C2410 | ||
65 | help | ||
66 | This option enables support for LEDs connected to GPIO lines | ||
67 | on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. | ||
68 | |||
62 | config LEDS_TRIGGER_TIMER | 69 | config LEDS_TRIGGER_TIMER |
63 | tristate "LED Timer Trigger" | 70 | tristate "LED Timer Trigger" |
64 | depends LEDS_TRIGGERS | 71 | depends LEDS_TRIGGERS |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 40699d3cabbf..40f042633bf5 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o | |||
10 | obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o | 10 | obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o |
11 | obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o | 11 | obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o |
12 | obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o | 12 | obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o |
13 | obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o | ||
13 | 14 | ||
14 | # LED Triggers | 15 | # LED Triggers |
15 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o | 16 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o |
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c new file mode 100644 index 000000000000..650cf72dc675 --- /dev/null +++ b/drivers/leds/leds-s3c24xx.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* drivers/leds/leds-s3c24xx.c | ||
2 | * | ||
3 | * (c) 2006 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C24XX - LEDs GPIO driver | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/leds.h> | ||
19 | |||
20 | #include <asm/arch/hardware.h> | ||
21 | #include <asm/arch/regs-gpio.h> | ||
22 | #include <asm/arch/leds-gpio.h> | ||
23 | |||
24 | /* our context */ | ||
25 | |||
26 | struct s3c24xx_gpio_led { | ||
27 | struct led_classdev cdev; | ||
28 | struct s3c24xx_led_platdata *pdata; | ||
29 | }; | ||
30 | |||
31 | static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev) | ||
32 | { | ||
33 | return platform_get_drvdata(dev); | ||
34 | } | ||
35 | |||
36 | static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev) | ||
37 | { | ||
38 | return container_of(led_cdev, struct s3c24xx_gpio_led, cdev); | ||
39 | } | ||
40 | |||
41 | static void s3c24xx_led_set(struct led_classdev *led_cdev, | ||
42 | enum led_brightness value) | ||
43 | { | ||
44 | struct s3c24xx_gpio_led *led = to_gpio(led_cdev); | ||
45 | struct s3c24xx_led_platdata *pd = led->pdata; | ||
46 | |||
47 | /* there will be a sort delay between setting the output and | ||
48 | * going from output to input when using tristate. */ | ||
49 | |||
50 | s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^ | ||
51 | (pd->flags & S3C24XX_LEDF_ACTLOW)); | ||
52 | |||
53 | if (pd->flags & S3C24XX_LEDF_TRISTATE) | ||
54 | s3c2410_gpio_cfgpin(pd->gpio, | ||
55 | value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT); | ||
56 | |||
57 | } | ||
58 | |||
59 | static int s3c24xx_led_remove(struct platform_device *dev) | ||
60 | { | ||
61 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
62 | |||
63 | led_classdev_unregister(&led->cdev); | ||
64 | kfree(led); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static int s3c24xx_led_probe(struct platform_device *dev) | ||
70 | { | ||
71 | struct s3c24xx_led_platdata *pdata = dev->dev.platform_data; | ||
72 | struct s3c24xx_gpio_led *led; | ||
73 | int ret; | ||
74 | |||
75 | led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL); | ||
76 | if (led == NULL) { | ||
77 | dev_err(&dev->dev, "No memory for device\n"); | ||
78 | return -ENOMEM; | ||
79 | } | ||
80 | |||
81 | platform_set_drvdata(dev, led); | ||
82 | |||
83 | led->cdev.brightness_set = s3c24xx_led_set; | ||
84 | led->cdev.default_trigger = pdata->def_trigger; | ||
85 | led->cdev.name = pdata->name; | ||
86 | |||
87 | led->pdata = pdata; | ||
88 | |||
89 | /* no point in having a pull-up if we are always driving */ | ||
90 | |||
91 | if (pdata->flags & S3C24XX_LEDF_TRISTATE) { | ||
92 | s3c2410_gpio_setpin(pdata->gpio, 0); | ||
93 | s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT); | ||
94 | } else { | ||
95 | s3c2410_gpio_pullup(pdata->gpio, 0); | ||
96 | s3c2410_gpio_setpin(pdata->gpio, 0); | ||
97 | s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT); | ||
98 | } | ||
99 | |||
100 | /* register our new led device */ | ||
101 | |||
102 | ret = led_classdev_register(&dev->dev, &led->cdev); | ||
103 | if (ret < 0) { | ||
104 | dev_err(&dev->dev, "led_classdev_register failed\n"); | ||
105 | goto exit_err1; | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | |||
110 | exit_err1: | ||
111 | kfree(led); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | |||
116 | #ifdef CONFIG_PM | ||
117 | static int s3c24xx_led_suspend(struct platform_device *dev, pm_message_t state) | ||
118 | { | ||
119 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
120 | |||
121 | led_classdev_suspend(&led->cdev); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int s3c24xx_led_resume(struct platform_device *dev) | ||
126 | { | ||
127 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
128 | |||
129 | led_classdev_resume(&led->cdev); | ||
130 | return 0; | ||
131 | } | ||
132 | #else | ||
133 | #define s3c24xx_led_suspend NULL | ||
134 | #define s3c24xx_led_resume NULL | ||
135 | #endif | ||
136 | |||
137 | static struct platform_driver s3c24xx_led_driver = { | ||
138 | .probe = s3c24xx_led_probe, | ||
139 | .remove = s3c24xx_led_remove, | ||
140 | .suspend = s3c24xx_led_suspend, | ||
141 | .resume = s3c24xx_led_resume, | ||
142 | .driver = { | ||
143 | .name = "s3c24xx_led", | ||
144 | .owner = THIS_MODULE, | ||
145 | }, | ||
146 | }; | ||
147 | |||
148 | static int __init s3c24xx_led_init(void) | ||
149 | { | ||
150 | return platform_driver_register(&s3c24xx_led_driver); | ||
151 | } | ||
152 | |||
153 | static void __exit s3c24xx_led_exit(void) | ||
154 | { | ||
155 | platform_driver_unregister(&s3c24xx_led_driver); | ||
156 | } | ||
157 | |||
158 | module_init(s3c24xx_led_init); | ||
159 | module_exit(s3c24xx_led_exit); | ||
160 | |||
161 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
162 | MODULE_DESCRIPTION("S3C24XX LED driver"); | ||
163 | MODULE_LICENSE("GPL"); | ||