Get rid of gpio shadowing.
[openwrt/staging/dedeckeh.git] / target / linux / s3c24xx / files-2.6.30 / drivers / leds / leds-gta02.c
1 /*
2 * LED driver for the Openmoko GTA02 GSM phone
3 *
4 * (C) 2006-2008 by Openmoko, Inc.
5 * Author: Harald Welte <laforge@openmoko.org>
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/platform_device.h>
17 #include <linux/leds.h>
18 #include <mach/hardware.h>
19 #include <asm/mach-types.h>
20 #include <mach/gta02.h>
21 #include <plat/regs-timer.h>
22
23 #define MAX_LEDS 3
24 #define COUNTER 256
25
26 struct gta02_led_priv
27 {
28 spinlock_t lock;
29 struct led_classdev cdev;
30 unsigned int gpio;
31 };
32
33 struct gta02_led_bundle
34 {
35 int num_leds;
36 struct gta02_led_priv led[MAX_LEDS];
37 };
38
39 static inline struct gta02_led_priv *to_priv(struct led_classdev *led_cdev)
40 {
41 return container_of(led_cdev, struct gta02_led_priv, cdev);
42 }
43
44 static inline struct gta02_led_bundle *to_bundle(struct led_classdev *led_cdev)
45 {
46 return dev_get_drvdata(led_cdev->dev->parent);
47 }
48
49 static void gta02led_set(struct led_classdev *led_cdev,
50 enum led_brightness value)
51 {
52 unsigned long flags;
53 struct gta02_led_priv *lp = to_priv(led_cdev);
54
55 spin_lock_irqsave(&lp->lock, flags);
56 s3c2410_gpio_setpin(lp->gpio, value ? 1 : 0);
57 spin_unlock_irqrestore(&lp->lock, flags);
58 }
59
60 #ifdef CONFIG_PM
61 static int gta02led_suspend(struct platform_device *pdev, pm_message_t state)
62 {
63 struct gta02_led_bundle *bundle = platform_get_drvdata(pdev);
64 int i;
65
66 for (i = 0; i < bundle->num_leds; i++)
67 led_classdev_suspend(&bundle->led[i].cdev);
68
69 return 0;
70 }
71
72 static int gta02led_resume(struct platform_device *pdev)
73 {
74 struct gta02_led_bundle *bundle = platform_get_drvdata(pdev);
75 int i;
76
77 for (i = 0; i < bundle->num_leds; i++)
78 led_classdev_resume(&bundle->led[i].cdev);
79
80 return 0;
81 }
82 #endif
83
84 static int __init gta02led_probe(struct platform_device *pdev)
85 {
86 int i, rc;
87 struct gta02_led_bundle *bundle;
88
89 if (!machine_is_neo1973_gta02())
90 return -EIO;
91
92 bundle = kzalloc(sizeof(struct gta02_led_bundle), GFP_KERNEL);
93 if (!bundle)
94 return -ENOMEM;
95 platform_set_drvdata(pdev, bundle);
96
97 for (i = 0; i < pdev->num_resources; i++) {
98 struct gta02_led_priv *lp;
99 struct resource *r;
100
101 if (i >= MAX_LEDS)
102 break;
103
104 r = platform_get_resource(pdev, 0, i);
105 if (!r || !r->start || !r->name)
106 continue;
107
108 lp = &bundle->led[i];
109
110 lp->gpio = r->start;
111 lp->cdev.name = r->name;
112 lp->cdev.brightness_set = gta02led_set;
113
114 switch (lp->gpio) {
115 case S3C2410_GPB0:
116 case S3C2410_GPB1:
117 case S3C2410_GPB2:
118 s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPIO_OUTPUT);
119 break;
120 default:
121 break;
122 }
123
124 spin_lock_init(&lp->lock);
125 rc = led_classdev_register(&pdev->dev, &lp->cdev);
126 }
127
128 bundle->num_leds = i;
129
130 return 0;
131 }
132
133 static int gta02led_remove(struct platform_device *pdev)
134 {
135 struct gta02_led_bundle *bundle = platform_get_drvdata(pdev);
136 int i;
137
138 for (i = 0; i < bundle->num_leds; i++) {
139 struct gta02_led_priv *lp = &bundle->led[i];
140 gta02led_set(&lp->cdev, 0);
141 led_classdev_unregister(&lp->cdev);
142 }
143
144 platform_set_drvdata(pdev, NULL);
145 kfree(bundle);
146
147 return 0;
148 }
149
150 static struct platform_driver gta02led_driver = {
151 .probe = gta02led_probe,
152 .remove = gta02led_remove,
153 #ifdef CONFIG_PM
154 .suspend = gta02led_suspend,
155 .resume = gta02led_resume,
156 #endif
157 .driver = {
158 .name = "gta02-led",
159 },
160 };
161
162 static int __init gta02led_init(void)
163 {
164 return platform_driver_register(&gta02led_driver);
165 }
166
167 static void __exit gta02led_exit(void)
168 {
169 platform_driver_unregister(&gta02led_driver);
170 }
171
172 module_init(gta02led_init);
173 module_exit(gta02led_exit);
174
175 MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
176 MODULE_DESCRIPTION("Openmoko GTA02 LED driver");
177 MODULE_LICENSE("GPL");