leds-ns2.c (998f468f34f41905051556a9897dbc204b1b75b4) leds-ns2.c (c29e650b3af272bedddc6c032148935e6f200cb7)
1/*
2 * leds-ns2.c - Driver for the Network Space v2 (and parents) dual-GPIO LED
3 *
4 * Copyright (C) 2010 LaCie
5 *
6 * Author: Simon Guinot <sguinot@lacie.com>
7 *
8 * Based on leds-gpio.c by Raphael Assenat <raph@8d.com>

--- 31 unchanged lines hidden (view full) ---

40 * for the command/slow GPIOs corresponds to a LED mode.
41 */
42
43struct ns2_led_data {
44 struct led_classdev cdev;
45 unsigned cmd;
46 unsigned slow;
47 bool can_sleep;
1/*
2 * leds-ns2.c - Driver for the Network Space v2 (and parents) dual-GPIO LED
3 *
4 * Copyright (C) 2010 LaCie
5 *
6 * Author: Simon Guinot <sguinot@lacie.com>
7 *
8 * Based on leds-gpio.c by Raphael Assenat <raph@8d.com>

--- 31 unchanged lines hidden (view full) ---

40 * for the command/slow GPIOs corresponds to a LED mode.
41 */
42
43struct ns2_led_data {
44 struct led_classdev cdev;
45 unsigned cmd;
46 unsigned slow;
47 bool can_sleep;
48 int mode_index;
49 unsigned char sata; /* True when SATA mode active. */
50 rwlock_t rw_lock; /* Lock GPIOs. */
48 unsigned char sata; /* True when SATA mode active. */
49 rwlock_t rw_lock; /* Lock GPIOs. */
51 struct work_struct work;
52 int num_modes;
53 struct ns2_led_modval *modval;
54};
55
50 int num_modes;
51 struct ns2_led_modval *modval;
52};
53
56static void ns2_led_work(struct work_struct *work)
57{
58 struct ns2_led_data *led_dat =
59 container_of(work, struct ns2_led_data, work);
60 int i = led_dat->mode_index;
61
62 gpio_set_value_cansleep(led_dat->cmd, led_dat->modval[i].cmd_level);
63 gpio_set_value_cansleep(led_dat->slow, led_dat->modval[i].slow_level);
64}
65
66static int ns2_led_get_mode(struct ns2_led_data *led_dat,
67 enum ns2_led_modes *mode)
68{
69 int i;
70 int ret = -EINVAL;
71 int cmd_level;
72 int slow_level;
73

--- 33 unchanged lines hidden (view full) ---

107 if (!led_dat->can_sleep) {
108 gpio_set_value(led_dat->cmd,
109 led_dat->modval[i].cmd_level);
110 gpio_set_value(led_dat->slow,
111 led_dat->modval[i].slow_level);
112 goto exit_unlock;
113 }
114
54static int ns2_led_get_mode(struct ns2_led_data *led_dat,
55 enum ns2_led_modes *mode)
56{
57 int i;
58 int ret = -EINVAL;
59 int cmd_level;
60 int slow_level;
61

--- 33 unchanged lines hidden (view full) ---

95 if (!led_dat->can_sleep) {
96 gpio_set_value(led_dat->cmd,
97 led_dat->modval[i].cmd_level);
98 gpio_set_value(led_dat->slow,
99 led_dat->modval[i].slow_level);
100 goto exit_unlock;
101 }
102
115 led_dat->mode_index = i;
116 schedule_work(&led_dat->work);
103 gpio_set_value_cansleep(led_dat->cmd, led_dat->modval[i].cmd_level);
104 gpio_set_value_cansleep(led_dat->slow, led_dat->modval[i].slow_level);
117
118exit_unlock:
119 write_unlock_irqrestore(&led_dat->rw_lock, flags);
120}
121
122static void ns2_led_set(struct led_classdev *led_cdev,
123 enum led_brightness value)
124{

--- 6 unchanged lines hidden (view full) ---

131 else if (led_dat->sata)
132 mode = NS_V2_LED_SATA;
133 else
134 mode = NS_V2_LED_ON;
135
136 ns2_led_set_mode(led_dat, mode);
137}
138
105
106exit_unlock:
107 write_unlock_irqrestore(&led_dat->rw_lock, flags);
108}
109
110static void ns2_led_set(struct led_classdev *led_cdev,
111 enum led_brightness value)
112{

--- 6 unchanged lines hidden (view full) ---

119 else if (led_dat->sata)
120 mode = NS_V2_LED_SATA;
121 else
122 mode = NS_V2_LED_ON;
123
124 ns2_led_set_mode(led_dat, mode);
125}
126
127static int ns2_led_set_blocking(struct led_classdev *led_cdev,
128 enum led_brightness value)
129{
130 ns2_led_set(led_cdev, value);
131 return 0;
132}
133
139static ssize_t ns2_led_sata_store(struct device *dev,
140 struct device_attribute *attr,
141 const char *buff, size_t count)
142{
143 struct led_classdev *led_cdev = dev_get_drvdata(dev);
144 struct ns2_led_data *led_dat =
145 container_of(led_cdev, struct ns2_led_data, cdev);
146 int ret;

--- 67 unchanged lines hidden (view full) ---

214 return ret;
215 }
216
217 rwlock_init(&led_dat->rw_lock);
218
219 led_dat->cdev.name = template->name;
220 led_dat->cdev.default_trigger = template->default_trigger;
221 led_dat->cdev.blink_set = NULL;
134static ssize_t ns2_led_sata_store(struct device *dev,
135 struct device_attribute *attr,
136 const char *buff, size_t count)
137{
138 struct led_classdev *led_cdev = dev_get_drvdata(dev);
139 struct ns2_led_data *led_dat =
140 container_of(led_cdev, struct ns2_led_data, cdev);
141 int ret;

--- 67 unchanged lines hidden (view full) ---

209 return ret;
210 }
211
212 rwlock_init(&led_dat->rw_lock);
213
214 led_dat->cdev.name = template->name;
215 led_dat->cdev.default_trigger = template->default_trigger;
216 led_dat->cdev.blink_set = NULL;
222 led_dat->cdev.brightness_set = ns2_led_set;
223 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
224 led_dat->cdev.groups = ns2_led_groups;
225 led_dat->cmd = template->cmd;
226 led_dat->slow = template->slow;
227 led_dat->can_sleep = gpio_cansleep(led_dat->cmd) |
228 gpio_cansleep(led_dat->slow);
217 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
218 led_dat->cdev.groups = ns2_led_groups;
219 led_dat->cmd = template->cmd;
220 led_dat->slow = template->slow;
221 led_dat->can_sleep = gpio_cansleep(led_dat->cmd) |
222 gpio_cansleep(led_dat->slow);
223 if (led_dat->can_sleep)
224 led_dat->cdev.brightness_set_blocking = ns2_led_set_blocking;
225 else
226 led_dat->cdev.brightness_set = ns2_led_set;
229 led_dat->modval = template->modval;
230 led_dat->num_modes = template->num_modes;
231
232 ret = ns2_led_get_mode(led_dat, &mode);
233 if (ret < 0)
234 return ret;
235
236 /* Set LED initial state. */
237 led_dat->sata = (mode == NS_V2_LED_SATA) ? 1 : 0;
238 led_dat->cdev.brightness =
239 (mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL;
240
227 led_dat->modval = template->modval;
228 led_dat->num_modes = template->num_modes;
229
230 ret = ns2_led_get_mode(led_dat, &mode);
231 if (ret < 0)
232 return ret;
233
234 /* Set LED initial state. */
235 led_dat->sata = (mode == NS_V2_LED_SATA) ? 1 : 0;
236 led_dat->cdev.brightness =
237 (mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL;
238
241 INIT_WORK(&led_dat->work, ns2_led_work);
242
243 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
244 if (ret < 0)
245 return ret;
246
247 return 0;
248}
249
250static void delete_ns2_led(struct ns2_led_data *led_dat)
251{
252 led_classdev_unregister(&led_dat->cdev);
239 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
240 if (ret < 0)
241 return ret;
242
243 return 0;
244}
245
246static void delete_ns2_led(struct ns2_led_data *led_dat)
247{
248 led_classdev_unregister(&led_dat->cdev);
253 cancel_work_sync(&led_dat->work);
254}
255
256#ifdef CONFIG_OF_GPIO
257/*
258 * Translate OpenFirmware node properties into platform_data.
259 */
260static int
261ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)

--- 165 unchanged lines hidden ---
249}
250
251#ifdef CONFIG_OF_GPIO
252/*
253 * Translate OpenFirmware node properties into platform_data.
254 */
255static int
256ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)

--- 165 unchanged lines hidden ---