aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-08-11 05:34:54 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-12 12:50:00 -0400
commit3e3b92cac5371031e9d2f916189577025f508ab8 (patch)
treea5fef17ed1b90cccfee9b08cd4a8805d421be954
parentcfc1b2a06f87f562da2ffb9f8d1ae4203d9bfbfa (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.c135
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
57enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; 62enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS };
58 63
59static void shark_led_set_blue(struct led_classdev *led_cdev,
60 enum led_brightness value);
61static void shark_led_set_blue_pulse(struct led_classdev *led_cdev,
62 enum led_brightness value);
63static void shark_led_set_red(struct led_classdev *led_cdev,
64 enum led_brightness value);
65
66static 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
87struct shark_device { 64struct 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
178static void shark_led_work(struct work_struct *work) 158static 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
218static 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
239static 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
260static 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
270static 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}
276static inline void shark_unregister_leds(struct shark_device *shark) { }
277#endif
278
238static void usb_shark_disconnect(struct usb_interface *intf) 279static 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
328err_init_tea: 349err_init_tea:
329 v4l2_device_unregister(&shark->v4l2_dev); 350 v4l2_device_unregister(&shark->v4l2_dev);
330err_reg_dev: 351err_reg_dev:
352 shark_unregister_leds(shark);
353err_reg_leds:
331 kfree(shark->transfer_buffer); 354 kfree(shark->transfer_buffer);
332err_alloc_buffer: 355err_alloc_buffer:
333 kfree(shark); 356 kfree(shark);