35
35
#include <media/v4l2-device.h>
36
36
#include "radio-tea5777.h"
37
37
38
+ #if defined(CONFIG_LEDS_CLASS ) || \
39
+ (defined(CONFIG_LEDS_CLASS_MODULE ) && defined(CONFIG_RADIO_SHARK2_MODULE ))
40
+ #define SHARK_USE_LEDS 1
41
+ #endif
42
+
38
43
MODULE_AUTHOR (
"Hans de Goede <[email protected] >" );
39
44
MODULE_DESCRIPTION ("Griffin radioSHARK2, USB radio receiver driver" );
40
45
MODULE_LICENSE ("GPL" );
@@ -43,7 +48,6 @@ static int debug;
43
48
module_param (debug , int , 0 );
44
49
MODULE_PARM_DESC (debug , "Debug level (0-1)" );
45
50
46
-
47
51
#define SHARK_IN_EP 0x83
48
52
#define SHARK_OUT_EP 0x05
49
53
@@ -54,36 +58,18 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
54
58
55
59
enum { BLUE_LED , RED_LED , NO_LEDS };
56
60
57
- static void shark_led_set_blue (struct led_classdev * led_cdev ,
58
- enum led_brightness value );
59
- static void shark_led_set_red (struct led_classdev * led_cdev ,
60
- enum led_brightness value );
61
-
62
- static const struct led_classdev shark_led_templates [NO_LEDS ] = {
63
- [BLUE_LED ] = {
64
- .name = "%s:blue:" ,
65
- .brightness = LED_OFF ,
66
- .max_brightness = 127 ,
67
- .brightness_set = shark_led_set_blue ,
68
- },
69
- [RED_LED ] = {
70
- .name = "%s:red:" ,
71
- .brightness = LED_OFF ,
72
- .max_brightness = 1 ,
73
- .brightness_set = shark_led_set_red ,
74
- },
75
- };
76
-
77
61
struct shark_device {
78
62
struct usb_device * usbdev ;
79
63
struct v4l2_device v4l2_dev ;
80
64
struct radio_tea5777 tea ;
81
65
66
+ #ifdef SHARK_USE_LEDS
82
67
struct work_struct led_work ;
83
68
struct led_classdev leds [NO_LEDS ];
84
69
char led_names [NO_LEDS ][32 ];
85
70
atomic_t brightness [NO_LEDS ];
86
71
unsigned long brightness_new ;
72
+ #endif
87
73
88
74
u8 * transfer_buffer ;
89
75
};
@@ -161,6 +147,7 @@ static struct radio_tea5777_ops shark_tea_ops = {
161
147
.read_reg = shark_read_reg ,
162
148
};
163
149
150
+ #ifdef SHARK_USE_LEDS
164
151
static void shark_led_work (struct work_struct * work )
165
152
{
166
153
struct shark_device * shark =
@@ -208,21 +195,72 @@ static void shark_led_set_red(struct led_classdev *led_cdev,
208
195
schedule_work (& shark -> led_work );
209
196
}
210
197
198
+ static const struct led_classdev shark_led_templates [NO_LEDS ] = {
199
+ [BLUE_LED ] = {
200
+ .name = "%s:blue:" ,
201
+ .brightness = LED_OFF ,
202
+ .max_brightness = 127 ,
203
+ .brightness_set = shark_led_set_blue ,
204
+ },
205
+ [RED_LED ] = {
206
+ .name = "%s:red:" ,
207
+ .brightness = LED_OFF ,
208
+ .max_brightness = 1 ,
209
+ .brightness_set = shark_led_set_red ,
210
+ },
211
+ };
212
+
213
+ static int shark_register_leds (struct shark_device * shark , struct device * dev )
214
+ {
215
+ int i , retval ;
216
+
217
+ INIT_WORK (& shark -> led_work , shark_led_work );
218
+ for (i = 0 ; i < NO_LEDS ; i ++ ) {
219
+ shark -> leds [i ] = shark_led_templates [i ];
220
+ snprintf (shark -> led_names [i ], sizeof (shark -> led_names [0 ]),
221
+ shark -> leds [i ].name , shark -> v4l2_dev .name );
222
+ shark -> leds [i ].name = shark -> led_names [i ];
223
+ retval = led_classdev_register (dev , & shark -> leds [i ]);
224
+ if (retval ) {
225
+ v4l2_err (& shark -> v4l2_dev ,
226
+ "couldn't register led: %s\n" ,
227
+ shark -> led_names [i ]);
228
+ return retval ;
229
+ }
230
+ }
231
+ return 0 ;
232
+ }
233
+
234
+ static void shark_unregister_leds (struct shark_device * shark )
235
+ {
236
+ int i ;
237
+
238
+ for (i = 0 ; i < NO_LEDS ; i ++ )
239
+ led_classdev_unregister (& shark -> leds [i ]);
240
+
241
+ cancel_work_sync (& shark -> led_work );
242
+ }
243
+ #else
244
+ static int shark_register_leds (struct shark_device * shark , struct device * dev )
245
+ {
246
+ v4l2_warn (& shark -> v4l2_dev ,
247
+ "CONFIG_LED_CLASS not enabled, LED support disabled\n" );
248
+ return 0 ;
249
+ }
250
+ static inline void shark_unregister_leds (struct shark_device * shark ) { }
251
+ #endif
252
+
211
253
static void usb_shark_disconnect (struct usb_interface * intf )
212
254
{
213
255
struct v4l2_device * v4l2_dev = usb_get_intfdata (intf );
214
256
struct shark_device * shark = v4l2_dev_to_shark (v4l2_dev );
215
- int i ;
216
257
217
258
mutex_lock (& shark -> tea .mutex );
218
259
v4l2_device_disconnect (& shark -> v4l2_dev );
219
260
radio_tea5777_exit (& shark -> tea );
220
261
mutex_unlock (& shark -> tea .mutex );
221
262
222
- for (i = 0 ; i < NO_LEDS ; i ++ )
223
- led_classdev_unregister (& shark -> leds [i ]);
224
-
225
- cancel_work_sync (& shark -> led_work );
263
+ shark_unregister_leds (shark );
226
264
227
265
v4l2_device_put (& shark -> v4l2_dev );
228
266
}
@@ -240,7 +278,7 @@ static int usb_shark_probe(struct usb_interface *intf,
240
278
const struct usb_device_id * id )
241
279
{
242
280
struct shark_device * shark ;
243
- int i , retval = - ENOMEM ;
281
+ int retval = - ENOMEM ;
244
282
245
283
shark = kzalloc (sizeof (struct shark_device ), GFP_KERNEL );
246
284
if (!shark )
@@ -250,8 +288,13 @@ static int usb_shark_probe(struct usb_interface *intf,
250
288
if (!shark -> transfer_buffer )
251
289
goto err_alloc_buffer ;
252
290
253
- shark -> v4l2_dev .release = usb_shark_release ;
254
291
v4l2_device_set_name (& shark -> v4l2_dev , DRV_NAME , & shark_instance );
292
+
293
+ retval = shark_register_leds (shark , & intf -> dev );
294
+ if (retval )
295
+ goto err_reg_leds ;
296
+
297
+ shark -> v4l2_dev .release = usb_shark_release ;
255
298
retval = v4l2_device_register (& intf -> dev , & shark -> v4l2_dev );
256
299
if (retval ) {
257
300
v4l2_err (& shark -> v4l2_dev , "couldn't register v4l2_device\n" );
@@ -275,32 +318,13 @@ static int usb_shark_probe(struct usb_interface *intf,
275
318
goto err_init_tea ;
276
319
}
277
320
278
- INIT_WORK (& shark -> led_work , shark_led_work );
279
- for (i = 0 ; i < NO_LEDS ; i ++ ) {
280
- shark -> leds [i ] = shark_led_templates [i ];
281
- snprintf (shark -> led_names [i ], sizeof (shark -> led_names [0 ]),
282
- shark -> leds [i ].name , shark -> v4l2_dev .name );
283
- shark -> leds [i ].name = shark -> led_names [i ];
284
- /*
285
- * We don't fail the probe if we fail to register the leds,
286
- * because once we've called radio_tea5777_init, the /dev/radio0
287
- * node may be opened from userspace holding a reference to us!
288
- *
289
- * Note we cannot register the leds first instead as
290
- * shark_led_work depends on the v4l2 mutex and registered bit.
291
- */
292
- retval = led_classdev_register (& intf -> dev , & shark -> leds [i ]);
293
- if (retval )
294
- v4l2_err (& shark -> v4l2_dev ,
295
- "couldn't register led: %s\n" ,
296
- shark -> led_names [i ]);
297
- }
298
-
299
321
return 0 ;
300
322
301
323
err_init_tea :
302
324
v4l2_device_unregister (& shark -> v4l2_dev );
303
325
err_reg_dev :
326
+ shark_unregister_leds (shark );
327
+ err_reg_leds :
304
328
kfree (shark -> transfer_buffer );
305
329
err_alloc_buffer :
306
330
kfree (shark );
0 commit comments