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 --- |