diff options
| -rw-r--r-- | drivers/hid/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-sony.c | 105 |
2 files changed, 44 insertions, 65 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 53caf0b115cb..5bad26ef227a 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -596,8 +596,8 @@ config HID_SAMSUNG | |||
| 596 | config HID_SONY | 596 | config HID_SONY |
| 597 | tristate "Sony PS2/3 accessories" | 597 | tristate "Sony PS2/3 accessories" |
| 598 | depends on USB_HID | 598 | depends on USB_HID |
| 599 | select NEW_LEDS | 599 | depends on NEW_LEDS |
| 600 | select LEDS_CLASS | 600 | depends on LEDS_CLASS |
| 601 | ---help--- | 601 | ---help--- |
| 602 | Support for | 602 | Support for |
| 603 | 603 | ||
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 41e829c8bc48..f1c906176615 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/usb.h> | 23 | #include <linux/usb.h> |
| 24 | #include <linux/leds.h> | ||
| 24 | 25 | ||
| 25 | #include "hid-ids.h" | 26 | #include "hid-ids.h" |
| 26 | 27 | ||
| @@ -103,10 +104,8 @@ struct sony_sc { | |||
| 103 | }; | 104 | }; |
| 104 | 105 | ||
| 105 | struct buzz_extra { | 106 | struct buzz_extra { |
| 106 | #ifdef CONFIG_LEDS_CLASS | ||
| 107 | int led_state; | 107 | int led_state; |
| 108 | struct led_classdev *leds[4]; | 108 | struct led_classdev *leds[4]; |
| 109 | #endif | ||
| 110 | }; | 109 | }; |
| 111 | 110 | ||
| 112 | /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ | 111 | /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ |
| @@ -274,7 +273,6 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev) | |||
| 274 | return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | 273 | return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); |
| 275 | } | 274 | } |
| 276 | 275 | ||
| 277 | #ifdef CONFIG_LEDS_CLASS | ||
| 278 | static void buzz_set_leds(struct hid_device *hdev, int leds) | 276 | static void buzz_set_leds(struct hid_device *hdev, int leds) |
| 279 | { | 277 | { |
| 280 | struct list_head *report_list = | 278 | struct list_head *report_list = |
| @@ -351,13 +349,15 @@ static enum led_brightness buzz_led_get_brightness(struct led_classdev *led) | |||
| 351 | 349 | ||
| 352 | return on ? LED_FULL : LED_OFF; | 350 | return on ? LED_FULL : LED_OFF; |
| 353 | } | 351 | } |
| 354 | #endif | ||
| 355 | 352 | ||
| 356 | static int buzz_init(struct hid_device *hdev) | 353 | static int buzz_init(struct hid_device *hdev) |
| 357 | { | 354 | { |
| 358 | struct sony_sc *drv_data; | 355 | struct sony_sc *drv_data; |
| 359 | struct buzz_extra *buzz; | 356 | struct buzz_extra *buzz; |
| 360 | int ret = 0; | 357 | int n, ret = 0; |
| 358 | struct led_classdev *led; | ||
| 359 | size_t name_sz; | ||
| 360 | char *name; | ||
| 361 | 361 | ||
| 362 | drv_data = hid_get_drvdata(hdev); | 362 | drv_data = hid_get_drvdata(hdev); |
| 363 | BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); | 363 | BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); |
| @@ -374,90 +374,69 @@ static int buzz_init(struct hid_device *hdev) | |||
| 374 | * LEDs to on */ | 374 | * LEDs to on */ |
| 375 | buzz_set_leds(hdev, 0x00); | 375 | buzz_set_leds(hdev, 0x00); |
| 376 | 376 | ||
| 377 | #ifdef CONFIG_LEDS_CLASS | 377 | name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1; |
| 378 | { | ||
| 379 | int n; | ||
| 380 | struct led_classdev *led; | ||
| 381 | size_t name_sz; | ||
| 382 | char *name; | ||
| 383 | 378 | ||
| 384 | name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1; | 379 | for (n = 0; n < 4; n++) { |
| 385 | 380 | led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); | |
| 386 | for (n = 0; n < 4; n++) { | 381 | if (!led) { |
| 387 | led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); | 382 | hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); |
| 388 | if (!led) { | 383 | goto error_leds; |
| 389 | hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); | 384 | } |
| 390 | goto error_leds; | ||
| 391 | } | ||
| 392 | 385 | ||
| 393 | name = (void *)(&led[1]); | 386 | name = (void *)(&led[1]); |
| 394 | snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1); | 387 | snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1); |
| 395 | led->name = name; | 388 | led->name = name; |
| 396 | led->brightness = 0; | 389 | led->brightness = 0; |
| 397 | led->max_brightness = 1; | 390 | led->max_brightness = 1; |
| 398 | led->brightness_get = buzz_led_get_brightness; | 391 | led->brightness_get = buzz_led_get_brightness; |
| 399 | led->brightness_set = buzz_led_set_brightness; | 392 | led->brightness_set = buzz_led_set_brightness; |
| 400 | |||
| 401 | if (led_classdev_register(&hdev->dev, led)) { | ||
| 402 | hid_err(hdev, "Failed to register LED %d\n", n); | ||
| 403 | kfree(led); | ||
| 404 | goto error_leds; | ||
| 405 | } | ||
| 406 | 393 | ||
| 407 | buzz->leds[n] = led; | 394 | if (led_classdev_register(&hdev->dev, led)) { |
| 395 | hid_err(hdev, "Failed to register LED %d\n", n); | ||
| 396 | kfree(led); | ||
| 397 | goto error_leds; | ||
| 408 | } | 398 | } |
| 399 | |||
| 400 | buzz->leds[n] = led; | ||
| 409 | } | 401 | } |
| 410 | #endif | ||
| 411 | 402 | ||
| 412 | return ret; | 403 | return ret; |
| 413 | 404 | ||
| 414 | #ifdef CONFIG_LEDS_CLASS | ||
| 415 | error_leds: | 405 | error_leds: |
| 416 | { | 406 | for (n = 0; n < 4; n++) { |
| 417 | int n; | 407 | led = buzz->leds[n]; |
| 418 | struct led_classdev *led; | 408 | buzz->leds[n] = NULL; |
| 419 | 409 | if (!led) | |
| 420 | for (n = 0; n < 4; n++) { | 410 | continue; |
| 421 | led = buzz->leds[n]; | 411 | led_classdev_unregister(led); |
| 422 | buzz->leds[n] = NULL; | 412 | kfree(led); |
| 423 | if (!led) | ||
| 424 | continue; | ||
| 425 | led_classdev_unregister(led); | ||
| 426 | kfree(led); | ||
| 427 | } | ||
| 428 | } | 413 | } |
| 429 | 414 | ||
| 430 | kfree(drv_data->extra); | 415 | kfree(drv_data->extra); |
| 431 | drv_data->extra = NULL; | 416 | drv_data->extra = NULL; |
| 432 | return ret; | 417 | return ret; |
| 433 | #endif | ||
| 434 | } | 418 | } |
| 435 | 419 | ||
| 436 | static void buzz_remove(struct hid_device *hdev) | 420 | static void buzz_remove(struct hid_device *hdev) |
| 437 | { | 421 | { |
| 438 | struct sony_sc *drv_data; | 422 | struct sony_sc *drv_data; |
| 439 | struct buzz_extra *buzz; | 423 | struct buzz_extra *buzz; |
| 424 | struct led_classdev *led; | ||
| 425 | int n; | ||
| 440 | 426 | ||
| 441 | drv_data = hid_get_drvdata(hdev); | 427 | drv_data = hid_get_drvdata(hdev); |
| 442 | BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); | 428 | BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); |
| 443 | 429 | ||
| 444 | buzz = drv_data->extra; | 430 | buzz = drv_data->extra; |
| 445 | 431 | ||
| 446 | #ifdef CONFIG_LEDS_CLASS | 432 | for (n = 0; n < 4; n++) { |
| 447 | { | 433 | led = buzz->leds[n]; |
| 448 | int n; | 434 | buzz->leds[n] = NULL; |
| 449 | struct led_classdev *led; | 435 | if (!led) |
| 450 | 436 | continue; | |
| 451 | for (n = 0; n < 4; n++) { | 437 | led_classdev_unregister(led); |
| 452 | led = buzz->leds[n]; | 438 | kfree(led); |
| 453 | buzz->leds[n] = NULL; | ||
| 454 | if (!led) | ||
| 455 | continue; | ||
| 456 | led_classdev_unregister(led); | ||
| 457 | kfree(led); | ||
| 458 | } | ||
| 459 | } | 439 | } |
| 460 | #endif | ||
| 461 | 440 | ||
| 462 | kfree(drv_data->extra); | 441 | kfree(drv_data->extra); |
| 463 | drv_data->extra = NULL; | 442 | drv_data->extra = NULL; |
