aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-09-05 03:17:31 -0400
committerTakashi Iwai <tiwai@suse.de>2012-09-05 03:17:31 -0400
commit14e42917216ab0859827c2d8024df45a917301b4 (patch)
treeefbea5d1c54387d62a6fd66a21560232cf312fda /drivers/media/radio
parent292f2b6254c9dbb98def6d3521b07a837545ead0 (diff)
parent4266274836e81575ee82498d84f4bd08ab7a7378 (diff)
Merge branch 'fixes' of git://git.alsa-project.org/alsa-kernel into for-next
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/radio-shark.c151
-rw-r--r--drivers/media/radio/radio-shark2.c137
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c3
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c5
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c2
5 files changed, 157 insertions, 141 deletions
diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c
index d0b6bb507634..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,20 +154,13 @@ 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 =
181 container_of(work, struct shark_device, led_work); 161 container_of(work, struct shark_device, led_work);
182 int i, res, brightness, actual_len; 162 int i, res, brightness, actual_len;
183 163
184 /*
185 * We use the v4l2_dev lock and registered bit to ensure the device
186 * does not get unplugged and unreffed while we're running.
187 */
188 mutex_lock(&shark->tea.mutex);
189 if (!video_is_registered(&shark->tea.vd))
190 goto leave;
191
192 for (i = 0; i < 3; i++) { 164 for (i = 0; i < 3; i++) {
193 if (!test_and_clear_bit(i, &shark->brightness_new)) 165 if (!test_and_clear_bit(i, &shark->brightness_new))
194 continue; 166 continue;
@@ -208,8 +180,6 @@ static void shark_led_work(struct work_struct *work)
208 v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", 180 v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n",
209 shark->led_names[i], res); 181 shark->led_names[i], res);
210 } 182 }
211leave:
212 mutex_unlock(&shark->tea.mutex);
213} 183}
214 184
215static void shark_led_set_blue(struct led_classdev *led_cdev, 185static void shark_led_set_blue(struct led_classdev *led_cdev,
@@ -245,19 +215,78 @@ static void shark_led_set_red(struct led_classdev *led_cdev,
245 schedule_work(&shark->led_work); 215 schedule_work(&shark->led_work);
246} 216}
247 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
248static void usb_shark_disconnect(struct usb_interface *intf) 279static void usb_shark_disconnect(struct usb_interface *intf)
249{ 280{
250 struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); 281 struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
251 struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); 282 struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
252 int i;
253 283
254 mutex_lock(&shark->tea.mutex); 284 mutex_lock(&shark->tea.mutex);
255 v4l2_device_disconnect(&shark->v4l2_dev); 285 v4l2_device_disconnect(&shark->v4l2_dev);
256 snd_tea575x_exit(&shark->tea); 286 snd_tea575x_exit(&shark->tea);
257 mutex_unlock(&shark->tea.mutex); 287 mutex_unlock(&shark->tea.mutex);
258 288
259 for (i = 0; i < NO_LEDS; i++) 289 shark_unregister_leds(shark);
260 led_classdev_unregister(&shark->leds[i]);
261 290
262 v4l2_device_put(&shark->v4l2_dev); 291 v4l2_device_put(&shark->v4l2_dev);
263} 292}
@@ -266,7 +295,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev)
266{ 295{
267 struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); 296 struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
268 297
269 cancel_work_sync(&shark->led_work);
270 v4l2_device_unregister(&shark->v4l2_dev); 298 v4l2_device_unregister(&shark->v4l2_dev);
271 kfree(shark->transfer_buffer); 299 kfree(shark->transfer_buffer);
272 kfree(shark); 300 kfree(shark);
@@ -276,7 +304,7 @@ static int usb_shark_probe(struct usb_interface *intf,
276 const struct usb_device_id *id) 304 const struct usb_device_id *id)
277{ 305{
278 struct shark_device *shark; 306 struct shark_device *shark;
279 int i, retval = -ENOMEM; 307 int retval = -ENOMEM;
280 308
281 shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); 309 shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
282 if (!shark) 310 if (!shark)
@@ -286,17 +314,13 @@ static int usb_shark_probe(struct usb_interface *intf,
286 if (!shark->transfer_buffer) 314 if (!shark->transfer_buffer)
287 goto err_alloc_buffer; 315 goto err_alloc_buffer;
288 316
289 /* 317 v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
290 * Work around a bug in usbhid/hid-core.c, where it leaves a dangling 318
291 * pointer in intfdata causing v4l2-device.c to not set it. Which 319 retval = shark_register_leds(shark, &intf->dev);
292 * results in usb_shark_disconnect() referencing the dangling pointer 320 if (retval)
293 * 321 goto err_reg_leds;
294 * REMOVE (as soon as the above bug is fixed, patch submitted)
295 */
296 usb_set_intfdata(intf, NULL);
297 322
298 shark->v4l2_dev.release = usb_shark_release; 323 shark->v4l2_dev.release = usb_shark_release;
299 v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
300 retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); 324 retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev);
301 if (retval) { 325 if (retval) {
302 v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); 326 v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n");
@@ -320,32 +344,13 @@ static int usb_shark_probe(struct usb_interface *intf,
320 goto err_init_tea; 344 goto err_init_tea;
321 } 345 }
322 346
323 INIT_WORK(&shark->led_work, shark_led_work);
324 for (i = 0; i < NO_LEDS; i++) {
325 shark->leds[i] = shark_led_templates[i];
326 snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
327 shark->leds[i].name, shark->v4l2_dev.name);
328 shark->leds[i].name = shark->led_names[i];
329 /*
330 * We don't fail the probe if we fail to register the leds,
331 * because once we've called snd_tea575x_init, the /dev/radio0
332 * node may be opened from userspace holding a reference to us!
333 *
334 * Note we cannot register the leds first instead as
335 * shark_led_work depends on the v4l2 mutex and registered bit.
336 */
337 retval = led_classdev_register(&intf->dev, &shark->leds[i]);
338 if (retval)
339 v4l2_err(&shark->v4l2_dev,
340 "couldn't register led: %s\n",
341 shark->led_names[i]);
342 }
343
344 return 0; 347 return 0;
345 348
346err_init_tea: 349err_init_tea:
347 v4l2_device_unregister(&shark->v4l2_dev); 350 v4l2_device_unregister(&shark->v4l2_dev);
348err_reg_dev: 351err_reg_dev:
352 shark_unregister_leds(shark);
353err_reg_leds:
349 kfree(shark->transfer_buffer); 354 kfree(shark->transfer_buffer);
350err_alloc_buffer: 355err_alloc_buffer:
351 kfree(shark); 356 kfree(shark);
diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c
index b9575de3e7e8..7b4efdfaae28 100644
--- a/drivers/media/radio/radio-shark2.c
+++ b/drivers/media/radio/radio-shark2.c
@@ -35,6 +35,11 @@
35#include <media/v4l2-device.h> 35#include <media/v4l2-device.h>
36#include "radio-tea5777.h" 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
38MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 43MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
39MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver"); 44MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver");
40MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
@@ -43,7 +48,6 @@ static int debug;
43module_param(debug, int, 0); 48module_param(debug, int, 0);
44MODULE_PARM_DESC(debug, "Debug level (0-1)"); 49MODULE_PARM_DESC(debug, "Debug level (0-1)");
45 50
46
47#define SHARK_IN_EP 0x83 51#define SHARK_IN_EP 0x83
48#define SHARK_OUT_EP 0x05 52#define SHARK_OUT_EP 0x05
49 53
@@ -54,36 +58,18 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
54 58
55enum { BLUE_LED, RED_LED, NO_LEDS }; 59enum { BLUE_LED, RED_LED, NO_LEDS };
56 60
57static void shark_led_set_blue(struct led_classdev *led_cdev,
58 enum led_brightness value);
59static void shark_led_set_red(struct led_classdev *led_cdev,
60 enum led_brightness value);
61
62static 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
77struct shark_device { 61struct shark_device {
78 struct usb_device *usbdev; 62 struct usb_device *usbdev;
79 struct v4l2_device v4l2_dev; 63 struct v4l2_device v4l2_dev;
80 struct radio_tea5777 tea; 64 struct radio_tea5777 tea;
81 65
66#ifdef SHARK_USE_LEDS
82 struct work_struct led_work; 67 struct work_struct led_work;
83 struct led_classdev leds[NO_LEDS]; 68 struct led_classdev leds[NO_LEDS];
84 char led_names[NO_LEDS][32]; 69 char led_names[NO_LEDS][32];
85 atomic_t brightness[NO_LEDS]; 70 atomic_t brightness[NO_LEDS];
86 unsigned long brightness_new; 71 unsigned long brightness_new;
72#endif
87 73
88 u8 *transfer_buffer; 74 u8 *transfer_buffer;
89}; 75};
@@ -161,18 +147,12 @@ static struct radio_tea5777_ops shark_tea_ops = {
161 .read_reg = shark_read_reg, 147 .read_reg = shark_read_reg,
162}; 148};
163 149
150#ifdef SHARK_USE_LEDS
164static void shark_led_work(struct work_struct *work) 151static void shark_led_work(struct work_struct *work)
165{ 152{
166 struct shark_device *shark = 153 struct shark_device *shark =
167 container_of(work, struct shark_device, led_work); 154 container_of(work, struct shark_device, led_work);
168 int i, res, brightness, actual_len; 155 int i, res, brightness, actual_len;
169 /*
170 * We use the v4l2_dev lock and registered bit to ensure the device
171 * does not get unplugged and unreffed while we're running.
172 */
173 mutex_lock(&shark->tea.mutex);
174 if (!video_is_registered(&shark->tea.vd))
175 goto leave;
176 156
177 for (i = 0; i < 2; i++) { 157 for (i = 0; i < 2; i++) {
178 if (!test_and_clear_bit(i, &shark->brightness_new)) 158 if (!test_and_clear_bit(i, &shark->brightness_new))
@@ -191,8 +171,6 @@ static void shark_led_work(struct work_struct *work)
191 v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", 171 v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n",
192 shark->led_names[i], res); 172 shark->led_names[i], res);
193 } 173 }
194leave:
195 mutex_unlock(&shark->tea.mutex);
196} 174}
197 175
198static void shark_led_set_blue(struct led_classdev *led_cdev, 176static void shark_led_set_blue(struct led_classdev *led_cdev,
@@ -217,19 +195,72 @@ static void shark_led_set_red(struct led_classdev *led_cdev,
217 schedule_work(&shark->led_work); 195 schedule_work(&shark->led_work);
218} 196}
219 197
198static 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
213static 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
234static 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
244static 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}
250static inline void shark_unregister_leds(struct shark_device *shark) { }
251#endif
252
220static void usb_shark_disconnect(struct usb_interface *intf) 253static void usb_shark_disconnect(struct usb_interface *intf)
221{ 254{
222 struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); 255 struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
223 struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); 256 struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
224 int i;
225 257
226 mutex_lock(&shark->tea.mutex); 258 mutex_lock(&shark->tea.mutex);
227 v4l2_device_disconnect(&shark->v4l2_dev); 259 v4l2_device_disconnect(&shark->v4l2_dev);
228 radio_tea5777_exit(&shark->tea); 260 radio_tea5777_exit(&shark->tea);
229 mutex_unlock(&shark->tea.mutex); 261 mutex_unlock(&shark->tea.mutex);
230 262
231 for (i = 0; i < NO_LEDS; i++) 263 shark_unregister_leds(shark);
232 led_classdev_unregister(&shark->leds[i]);
233 264
234 v4l2_device_put(&shark->v4l2_dev); 265 v4l2_device_put(&shark->v4l2_dev);
235} 266}
@@ -238,7 +269,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev)
238{ 269{
239 struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); 270 struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
240 271
241 cancel_work_sync(&shark->led_work);
242 v4l2_device_unregister(&shark->v4l2_dev); 272 v4l2_device_unregister(&shark->v4l2_dev);
243 kfree(shark->transfer_buffer); 273 kfree(shark->transfer_buffer);
244 kfree(shark); 274 kfree(shark);
@@ -248,7 +278,7 @@ static int usb_shark_probe(struct usb_interface *intf,
248 const struct usb_device_id *id) 278 const struct usb_device_id *id)
249{ 279{
250 struct shark_device *shark; 280 struct shark_device *shark;
251 int i, retval = -ENOMEM; 281 int retval = -ENOMEM;
252 282
253 shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); 283 shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
254 if (!shark) 284 if (!shark)
@@ -258,17 +288,13 @@ static int usb_shark_probe(struct usb_interface *intf,
258 if (!shark->transfer_buffer) 288 if (!shark->transfer_buffer)
259 goto err_alloc_buffer; 289 goto err_alloc_buffer;
260 290
261 /* 291 v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
262 * Work around a bug in usbhid/hid-core.c, where it leaves a dangling 292
263 * pointer in intfdata causing v4l2-device.c to not set it. Which 293 retval = shark_register_leds(shark, &intf->dev);
264 * results in usb_shark_disconnect() referencing the dangling pointer 294 if (retval)
265 * 295 goto err_reg_leds;
266 * REMOVE (as soon as the above bug is fixed, patch submitted)
267 */
268 usb_set_intfdata(intf, NULL);
269 296
270 shark->v4l2_dev.release = usb_shark_release; 297 shark->v4l2_dev.release = usb_shark_release;
271 v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
272 retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); 298 retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev);
273 if (retval) { 299 if (retval) {
274 v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); 300 v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n");
@@ -292,32 +318,13 @@ static int usb_shark_probe(struct usb_interface *intf,
292 goto err_init_tea; 318 goto err_init_tea;
293 } 319 }
294 320
295 INIT_WORK(&shark->led_work, shark_led_work);
296 for (i = 0; i < NO_LEDS; i++) {
297 shark->leds[i] = shark_led_templates[i];
298 snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
299 shark->leds[i].name, shark->v4l2_dev.name);
300 shark->leds[i].name = shark->led_names[i];
301 /*
302 * We don't fail the probe if we fail to register the leds,
303 * because once we've called radio_tea5777_init, the /dev/radio0
304 * node may be opened from userspace holding a reference to us!
305 *
306 * Note we cannot register the leds first instead as
307 * shark_led_work depends on the v4l2 mutex and registered bit.
308 */
309 retval = led_classdev_register(&intf->dev, &shark->leds[i]);
310 if (retval)
311 v4l2_err(&shark->v4l2_dev,
312 "couldn't register led: %s\n",
313 shark->led_names[i]);
314 }
315
316 return 0; 321 return 0;
317 322
318err_init_tea: 323err_init_tea:
319 v4l2_device_unregister(&shark->v4l2_dev); 324 v4l2_device_unregister(&shark->v4l2_dev);
320err_reg_dev: 325err_reg_dev:
326 shark_unregister_leds(shark);
327err_reg_leds:
321 kfree(shark->transfer_buffer); 328 kfree(shark->transfer_buffer);
322err_alloc_buffer: 329err_alloc_buffer:
323 kfree(shark); 330 kfree(shark);
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 9e38132afec6..9bb65e170d99 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -151,6 +151,7 @@ static const struct v4l2_frequency_band bands[] = {
151 .index = 0, 151 .index = 0,
152 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | 152 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
153 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | 153 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
154 V4L2_TUNER_CAP_FREQ_BANDS |
154 V4L2_TUNER_CAP_HWSEEK_BOUNDED | 155 V4L2_TUNER_CAP_HWSEEK_BOUNDED |
155 V4L2_TUNER_CAP_HWSEEK_WRAP, 156 V4L2_TUNER_CAP_HWSEEK_WRAP,
156 .rangelow = 87500 * 16, 157 .rangelow = 87500 * 16,
@@ -162,6 +163,7 @@ static const struct v4l2_frequency_band bands[] = {
162 .index = 1, 163 .index = 1,
163 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | 164 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
164 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | 165 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
166 V4L2_TUNER_CAP_FREQ_BANDS |
165 V4L2_TUNER_CAP_HWSEEK_BOUNDED | 167 V4L2_TUNER_CAP_HWSEEK_BOUNDED |
166 V4L2_TUNER_CAP_HWSEEK_WRAP, 168 V4L2_TUNER_CAP_HWSEEK_WRAP,
167 .rangelow = 76000 * 16, 169 .rangelow = 76000 * 16,
@@ -173,6 +175,7 @@ static const struct v4l2_frequency_band bands[] = {
173 .index = 2, 175 .index = 2,
174 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | 176 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
175 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | 177 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
178 V4L2_TUNER_CAP_FREQ_BANDS |
176 V4L2_TUNER_CAP_HWSEEK_BOUNDED | 179 V4L2_TUNER_CAP_HWSEEK_BOUNDED |
177 V4L2_TUNER_CAP_HWSEEK_WRAP, 180 V4L2_TUNER_CAP_HWSEEK_WRAP,
178 .rangelow = 76000 * 16, 181 .rangelow = 76000 * 16,
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 643a6ff7c5d0..f867f04cccc9 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -225,8 +225,9 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
225{ 225{
226 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); 226 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
227 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); 227 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
228 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | 228 capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE |
229 V4L2_CAP_TUNER | V4L2_CAP_RADIO; 229 V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
230 capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
230 231
231 return 0; 232 return 0;
232} 233}
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index 146be4263ea1..be076f7181e7 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -531,7 +531,7 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
531 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); 531 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
532 usb_make_path(radio->usbdev, capability->bus_info, 532 usb_make_path(radio->usbdev, capability->bus_info,
533 sizeof(capability->bus_info)); 533 sizeof(capability->bus_info));
534 capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | 534 capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE |
535 V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; 535 V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
536 capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; 536 capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
537 return 0; 537 return 0;