diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-driver-hid-srws1 | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-steelseries-srws1.c | 65 |
2 files changed, 62 insertions, 4 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-srws1 b/Documentation/ABI/testing/sysfs-driver-hid-srws1 index c27b34dcaf83..d0eba70c7d40 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-srws1 +++ b/Documentation/ABI/testing/sysfs-driver-hid-srws1 | |||
| @@ -13,6 +13,7 @@ What: /sys/class/leds/SRWS1::<serial>::RPM12 | |||
| 13 | What: /sys/class/leds/SRWS1::<serial>::RPM13 | 13 | What: /sys/class/leds/SRWS1::<serial>::RPM13 |
| 14 | What: /sys/class/leds/SRWS1::<serial>::RPM14 | 14 | What: /sys/class/leds/SRWS1::<serial>::RPM14 |
| 15 | What: /sys/class/leds/SRWS1::<serial>::RPM15 | 15 | What: /sys/class/leds/SRWS1::<serial>::RPM15 |
| 16 | What: /sys/class/leds/SRWS1::<serial>::RPMALL | ||
| 16 | Date: Jan 2013 | 17 | Date: Jan 2013 |
| 17 | KernelVersion: 3.9 | 18 | KernelVersion: 3.9 |
| 18 | Contact: Simon Wood <simon@mungewell.org> | 19 | Contact: Simon Wood <simon@mungewell.org> |
diff --git a/drivers/hid/hid-steelseries-srws1.c b/drivers/hid/hid-steelseries-srws1.c index a7386699ba7d..365bc9ef1e79 100644 --- a/drivers/hid/hid-steelseries-srws1.c +++ b/drivers/hid/hid-steelseries-srws1.c | |||
| @@ -136,6 +136,42 @@ static void steelseries_srws1_set_leds(struct hid_device *hdev, __u16 leds) | |||
| 136 | /* Note: LED change does not show on device until the device is read/polled */ | 136 | /* Note: LED change does not show on device until the device is read/polled */ |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | static void steelseries_srws1_led_all_set_brightness(struct led_classdev *led_cdev, | ||
| 140 | enum led_brightness value) | ||
| 141 | { | ||
| 142 | struct device *dev = led_cdev->dev->parent; | ||
| 143 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
| 144 | struct steelseries_srws1_data *drv_data = hid_get_drvdata(hid); | ||
| 145 | |||
| 146 | if (!drv_data) { | ||
| 147 | hid_err(hid, "Device data not found."); | ||
| 148 | return; | ||
| 149 | } | ||
| 150 | |||
| 151 | if (value == LED_OFF) | ||
| 152 | drv_data->led_state = 0; | ||
| 153 | else | ||
| 154 | drv_data->led_state = (1 << (SRWS1_NUMBER_LEDS + 1)) - 1; | ||
| 155 | |||
| 156 | steelseries_srws1_set_leds(hid, drv_data->led_state); | ||
| 157 | } | ||
| 158 | |||
| 159 | static enum led_brightness steelseries_srws1_led_all_get_brightness(struct led_classdev *led_cdev) | ||
| 160 | { | ||
| 161 | struct device *dev = led_cdev->dev->parent; | ||
| 162 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
| 163 | struct steelseries_srws1_data *drv_data; | ||
| 164 | |||
| 165 | drv_data = hid_get_drvdata(hid); | ||
| 166 | |||
| 167 | if (!drv_data) { | ||
| 168 | hid_err(hid, "Device data not found."); | ||
| 169 | return LED_OFF; | ||
| 170 | } | ||
| 171 | |||
| 172 | return (drv_data->led_state >> SRWS1_NUMBER_LEDS) ? LED_FULL : LED_OFF; | ||
| 173 | } | ||
| 174 | |||
| 139 | static void steelseries_srws1_led_set_brightness(struct led_classdev *led_cdev, | 175 | static void steelseries_srws1_led_set_brightness(struct led_classdev *led_cdev, |
| 140 | enum led_brightness value) | 176 | enum led_brightness value) |
| 141 | { | 177 | { |
| @@ -219,13 +255,34 @@ static int steelseries_srws1_probe(struct hid_device *hdev, | |||
| 219 | 255 | ||
| 220 | /* register led subsystem */ | 256 | /* register led subsystem */ |
| 221 | drv_data->led_state = 0; | 257 | drv_data->led_state = 0; |
| 222 | for (i = 0; i < SRWS1_NUMBER_LEDS; i++) | 258 | for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) |
| 223 | drv_data->led[i] = NULL; | 259 | drv_data->led[i] = NULL; |
| 224 | 260 | ||
| 225 | steelseries_srws1_set_leds(hdev, 0); | 261 | steelseries_srws1_set_leds(hdev, 0); |
| 226 | 262 | ||
| 227 | name_sz = strlen(hdev->uniq) + 15; | 263 | name_sz = strlen(hdev->uniq) + 16; |
| 264 | |||
| 265 | /* 'ALL', for setting all LEDs simultaneously */ | ||
| 266 | led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); | ||
| 267 | if (!led) { | ||
| 268 | hid_err(hdev, "can't allocate memory for LED ALL\n"); | ||
| 269 | goto err_led; | ||
| 270 | } | ||
| 271 | |||
| 272 | name = (void *)(&led[1]); | ||
| 273 | snprintf(name, name_sz, "SRWS1::%s::RPMALL", hdev->uniq); | ||
| 274 | led->name = name; | ||
| 275 | led->brightness = 0; | ||
| 276 | led->max_brightness = 1; | ||
| 277 | led->brightness_get = steelseries_srws1_led_all_get_brightness; | ||
| 278 | led->brightness_set = steelseries_srws1_led_all_set_brightness; | ||
| 279 | |||
| 280 | drv_data->led[SRWS1_NUMBER_LEDS] = led; | ||
| 281 | ret = led_classdev_register(&hdev->dev, led); | ||
| 282 | if (ret) | ||
| 283 | goto err_led; | ||
| 228 | 284 | ||
| 285 | /* Each individual LED */ | ||
| 229 | for (i = 0; i < SRWS1_NUMBER_LEDS; i++) { | 286 | for (i = 0; i < SRWS1_NUMBER_LEDS; i++) { |
| 230 | led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); | 287 | led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); |
| 231 | if (!led) { | 288 | if (!led) { |
| @@ -248,7 +305,7 @@ static int steelseries_srws1_probe(struct hid_device *hdev, | |||
| 248 | hid_err(hdev, "failed to register LED %d. Aborting.\n", i); | 305 | hid_err(hdev, "failed to register LED %d. Aborting.\n", i); |
| 249 | err_led: | 306 | err_led: |
| 250 | /* Deregister all LEDs (if any) */ | 307 | /* Deregister all LEDs (if any) */ |
| 251 | for (i = 0; i < SRWS1_NUMBER_LEDS; i++) { | 308 | for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) { |
| 252 | led = drv_data->led[i]; | 309 | led = drv_data->led[i]; |
| 253 | drv_data->led[i] = NULL; | 310 | drv_data->led[i] = NULL; |
| 254 | if (!led) | 311 | if (!led) |
| @@ -275,7 +332,7 @@ static void steelseries_srws1_remove(struct hid_device *hdev) | |||
| 275 | 332 | ||
| 276 | if (drv_data) { | 333 | if (drv_data) { |
| 277 | /* Deregister LEDs (if any) */ | 334 | /* Deregister LEDs (if any) */ |
| 278 | for (i = 0; i < SRWS1_NUMBER_LEDS; i++) { | 335 | for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) { |
| 279 | led = drv_data->led[i]; | 336 | led = drv_data->led[i]; |
| 280 | drv_data->led[i] = NULL; | 337 | drv_data->led[i] = NULL; |
| 281 | if (!led) | 338 | if (!led) |
