diff options
| author | Hans de Goede <hdegoede@redhat.com> | 2012-08-11 05:34:54 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-12 12:50:00 -0400 |
| commit | 3e3b92cac5371031e9d2f916189577025f508ab8 (patch) | |
| tree | a5fef17ed1b90cccfee9b08cd4a8805d421be954 | |
| parent | cfc1b2a06f87f562da2ffb9f8d1ae4203d9bfbfa (diff) | |
[media] radio-shark: Only compile led support when CONFIG_LED_CLASS is set
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/radio/radio-shark.c | 135 |
1 files changed, 79 insertions, 56 deletions
diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c index 1d76afa9e1b7..72ded29728bb 100644 --- a/drivers/media/radio/radio-shark.c +++ b/drivers/media/radio/radio-shark.c | |||
| @@ -35,6 +35,11 @@ | |||
| 35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
| 36 | #include <sound/tea575x-tuner.h> | 36 | #include <sound/tea575x-tuner.h> |
| 37 | 37 | ||
| 38 | #if defined(CONFIG_LEDS_CLASS) || \ | ||
| 39 | (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK_MODULE)) | ||
| 40 | #define SHARK_USE_LEDS 1 | ||
| 41 | #endif | ||
| 42 | |||
| 38 | /* | 43 | /* |
| 39 | * Version Information | 44 | * Version Information |
| 40 | */ | 45 | */ |
| @@ -56,44 +61,18 @@ MODULE_LICENSE("GPL"); | |||
| 56 | 61 | ||
| 57 | enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; | 62 | enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; |
| 58 | 63 | ||
| 59 | static void shark_led_set_blue(struct led_classdev *led_cdev, | ||
| 60 | enum led_brightness value); | ||
| 61 | static void shark_led_set_blue_pulse(struct led_classdev *led_cdev, | ||
| 62 | enum led_brightness value); | ||
| 63 | static void shark_led_set_red(struct led_classdev *led_cdev, | ||
| 64 | enum led_brightness value); | ||
| 65 | |||
| 66 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
| 67 | [BLUE_LED] = { | ||
| 68 | .name = "%s:blue:", | ||
| 69 | .brightness = LED_OFF, | ||
| 70 | .max_brightness = 127, | ||
| 71 | .brightness_set = shark_led_set_blue, | ||
| 72 | }, | ||
| 73 | [BLUE_PULSE_LED] = { | ||
| 74 | .name = "%s:blue-pulse:", | ||
| 75 | .brightness = LED_OFF, | ||
| 76 | .max_brightness = 255, | ||
| 77 | .brightness_set = shark_led_set_blue_pulse, | ||
| 78 | }, | ||
| 79 | [RED_LED] = { | ||
| 80 | .name = "%s:red:", | ||
| 81 | .brightness = LED_OFF, | ||
| 82 | .max_brightness = 1, | ||
| 83 | .brightness_set = shark_led_set_red, | ||
| 84 | }, | ||
| 85 | }; | ||
| 86 | |||
| 87 | struct shark_device { | 64 | struct shark_device { |
| 88 | struct usb_device *usbdev; | 65 | struct usb_device *usbdev; |
| 89 | struct v4l2_device v4l2_dev; | 66 | struct v4l2_device v4l2_dev; |
| 90 | struct snd_tea575x tea; | 67 | struct snd_tea575x tea; |
| 91 | 68 | ||
| 69 | #ifdef SHARK_USE_LEDS | ||
| 92 | struct work_struct led_work; | 70 | struct work_struct led_work; |
| 93 | struct led_classdev leds[NO_LEDS]; | 71 | struct led_classdev leds[NO_LEDS]; |
| 94 | char led_names[NO_LEDS][32]; | 72 | char led_names[NO_LEDS][32]; |
| 95 | atomic_t brightness[NO_LEDS]; | 73 | atomic_t brightness[NO_LEDS]; |
| 96 | unsigned long brightness_new; | 74 | unsigned long brightness_new; |
| 75 | #endif | ||
| 97 | 76 | ||
| 98 | u8 *transfer_buffer; | 77 | u8 *transfer_buffer; |
| 99 | u32 last_val; | 78 | u32 last_val; |
| @@ -175,6 +154,7 @@ static struct snd_tea575x_ops shark_tea_ops = { | |||
| 175 | .read_val = shark_read_val, | 154 | .read_val = shark_read_val, |
| 176 | }; | 155 | }; |
| 177 | 156 | ||
| 157 | #ifdef SHARK_USE_LEDS | ||
| 178 | static void shark_led_work(struct work_struct *work) | 158 | static void shark_led_work(struct work_struct *work) |
| 179 | { | 159 | { |
| 180 | struct shark_device *shark = | 160 | struct shark_device *shark = |
| @@ -235,21 +215,78 @@ static void shark_led_set_red(struct led_classdev *led_cdev, | |||
| 235 | schedule_work(&shark->led_work); | 215 | schedule_work(&shark->led_work); |
| 236 | } | 216 | } |
| 237 | 217 | ||
| 218 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
| 219 | [BLUE_LED] = { | ||
| 220 | .name = "%s:blue:", | ||
| 221 | .brightness = LED_OFF, | ||
| 222 | .max_brightness = 127, | ||
| 223 | .brightness_set = shark_led_set_blue, | ||
| 224 | }, | ||
| 225 | [BLUE_PULSE_LED] = { | ||
| 226 | .name = "%s:blue-pulse:", | ||
| 227 | .brightness = LED_OFF, | ||
| 228 | .max_brightness = 255, | ||
| 229 | .brightness_set = shark_led_set_blue_pulse, | ||
| 230 | }, | ||
| 231 | [RED_LED] = { | ||
| 232 | .name = "%s:red:", | ||
| 233 | .brightness = LED_OFF, | ||
| 234 | .max_brightness = 1, | ||
| 235 | .brightness_set = shark_led_set_red, | ||
| 236 | }, | ||
| 237 | }; | ||
| 238 | |||
| 239 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
| 240 | { | ||
| 241 | int i, retval; | ||
| 242 | |||
| 243 | INIT_WORK(&shark->led_work, shark_led_work); | ||
| 244 | for (i = 0; i < NO_LEDS; i++) { | ||
| 245 | shark->leds[i] = shark_led_templates[i]; | ||
| 246 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
| 247 | shark->leds[i].name, shark->v4l2_dev.name); | ||
| 248 | shark->leds[i].name = shark->led_names[i]; | ||
| 249 | retval = led_classdev_register(dev, &shark->leds[i]); | ||
| 250 | if (retval) { | ||
| 251 | v4l2_err(&shark->v4l2_dev, | ||
| 252 | "couldn't register led: %s\n", | ||
| 253 | shark->led_names[i]); | ||
| 254 | return retval; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | return 0; | ||
| 258 | } | ||
| 259 | |||
| 260 | static void shark_unregister_leds(struct shark_device *shark) | ||
| 261 | { | ||
| 262 | int i; | ||
| 263 | |||
| 264 | for (i = 0; i < NO_LEDS; i++) | ||
| 265 | led_classdev_unregister(&shark->leds[i]); | ||
| 266 | |||
| 267 | cancel_work_sync(&shark->led_work); | ||
| 268 | } | ||
| 269 | #else | ||
| 270 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
| 271 | { | ||
| 272 | v4l2_warn(&shark->v4l2_dev, | ||
| 273 | "CONFIG_LED_CLASS not enabled, LED support disabled\n"); | ||
| 274 | return 0; | ||
| 275 | } | ||
| 276 | static inline void shark_unregister_leds(struct shark_device *shark) { } | ||
| 277 | #endif | ||
| 278 | |||
| 238 | static void usb_shark_disconnect(struct usb_interface *intf) | 279 | static void usb_shark_disconnect(struct usb_interface *intf) |
| 239 | { | 280 | { |
| 240 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); | 281 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); |
| 241 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 282 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
| 242 | int i; | ||
| 243 | 283 | ||
| 244 | mutex_lock(&shark->tea.mutex); | 284 | mutex_lock(&shark->tea.mutex); |
| 245 | v4l2_device_disconnect(&shark->v4l2_dev); | 285 | v4l2_device_disconnect(&shark->v4l2_dev); |
| 246 | snd_tea575x_exit(&shark->tea); | 286 | snd_tea575x_exit(&shark->tea); |
| 247 | mutex_unlock(&shark->tea.mutex); | 287 | mutex_unlock(&shark->tea.mutex); |
| 248 | 288 | ||
| 249 | for (i = 0; i < NO_LEDS; i++) | 289 | shark_unregister_leds(shark); |
| 250 | led_classdev_unregister(&shark->leds[i]); | ||
| 251 | |||
| 252 | cancel_work_sync(&shark->led_work); | ||
| 253 | 290 | ||
| 254 | v4l2_device_put(&shark->v4l2_dev); | 291 | v4l2_device_put(&shark->v4l2_dev); |
| 255 | } | 292 | } |
| @@ -267,7 +304,7 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
| 267 | const struct usb_device_id *id) | 304 | const struct usb_device_id *id) |
| 268 | { | 305 | { |
| 269 | struct shark_device *shark; | 306 | struct shark_device *shark; |
| 270 | int i, retval = -ENOMEM; | 307 | int retval = -ENOMEM; |
| 271 | 308 | ||
| 272 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); | 309 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); |
| 273 | if (!shark) | 310 | if (!shark) |
| @@ -277,8 +314,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
| 277 | if (!shark->transfer_buffer) | 314 | if (!shark->transfer_buffer) |
| 278 | goto err_alloc_buffer; | 315 | goto err_alloc_buffer; |
| 279 | 316 | ||
| 280 | shark->v4l2_dev.release = usb_shark_release; | ||
| 281 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); | 317 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); |
| 318 | |||
| 319 | retval = shark_register_leds(shark, &intf->dev); | ||
| 320 | if (retval) | ||
| 321 | goto err_reg_leds; | ||
| 322 | |||
| 323 | shark->v4l2_dev.release = usb_shark_release; | ||
| 282 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); | 324 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); |
| 283 | if (retval) { | 325 | if (retval) { |
| 284 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); | 326 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); |
| @@ -302,32 +344,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
| 302 | goto err_init_tea; | 344 | goto err_init_tea; |
| 303 | } | 345 | } |
| 304 | 346 | ||
| 305 | INIT_WORK(&shark->led_work, shark_led_work); | ||
| 306 | for (i = 0; i < NO_LEDS; i++) { | ||
| 307 | shark->leds[i] = shark_led_templates[i]; | ||
| 308 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
| 309 | shark->leds[i].name, shark->v4l2_dev.name); | ||
| 310 | shark->leds[i].name = shark->led_names[i]; | ||
| 311 | /* | ||
| 312 | * We don't fail the probe if we fail to register the leds, | ||
| 313 | * because once we've called snd_tea575x_init, the /dev/radio0 | ||
| 314 | * node may be opened from userspace holding a reference to us! | ||
| 315 | * | ||
| 316 | * Note we cannot register the leds first instead as | ||
| 317 | * shark_led_work depends on the v4l2 mutex and registered bit. | ||
| 318 | */ | ||
| 319 | retval = led_classdev_register(&intf->dev, &shark->leds[i]); | ||
| 320 | if (retval) | ||
| 321 | v4l2_err(&shark->v4l2_dev, | ||
| 322 | "couldn't register led: %s\n", | ||
| 323 | shark->led_names[i]); | ||
| 324 | } | ||
| 325 | |||
| 326 | return 0; | 347 | return 0; |
| 327 | 348 | ||
| 328 | err_init_tea: | 349 | err_init_tea: |
| 329 | v4l2_device_unregister(&shark->v4l2_dev); | 350 | v4l2_device_unregister(&shark->v4l2_dev); |
| 330 | err_reg_dev: | 351 | err_reg_dev: |
| 352 | shark_unregister_leds(shark); | ||
| 353 | err_reg_leds: | ||
| 331 | kfree(shark->transfer_buffer); | 354 | kfree(shark->transfer_buffer); |
| 332 | err_alloc_buffer: | 355 | err_alloc_buffer: |
| 333 | kfree(shark); | 356 | kfree(shark); |
