aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/dsbr100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/dsbr100.c')
-rw-r--r--drivers/media/radio/dsbr100.c381
1 files changed, 290 insertions, 91 deletions
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index a5ca176a7b08..5474a22c1b22 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -1,5 +1,5 @@
1/* A driver for the D-Link DSB-R100 USB radio. The R100 plugs 1/* A driver for the D-Link DSB-R100 USB radio and Gemtek USB Radio 21.
2 into both the USB and an analog audio input, so this thing 2 The device plugs into both the USB and an analog audio input, so this thing
3 only deals with initialisation and frequency setting, the 3 only deals with initialisation and frequency setting, the
4 audio data has to be handled by a sound driver. 4 audio data has to be handled by a sound driver.
5 5
@@ -33,6 +33,10 @@
33 33
34 History: 34 History:
35 35
36 Version 0.44:
37 Add suspend/resume functions, fix unplug of device,
38 a lot of cleanups and fixes by Alexey Klimov <klimov.linux@gmail.com>
39
36 Version 0.43: 40 Version 0.43:
37 Oliver Neukum: avoided DMA coherency issue 41 Oliver Neukum: avoided DMA coherency issue
38 42
@@ -93,8 +97,8 @@
93 */ 97 */
94#include <linux/version.h> /* for KERNEL_VERSION MACRO */ 98#include <linux/version.h> /* for KERNEL_VERSION MACRO */
95 99
96#define DRIVER_VERSION "v0.41" 100#define DRIVER_VERSION "v0.44"
97#define RADIO_VERSION KERNEL_VERSION(0,4,1) 101#define RADIO_VERSION KERNEL_VERSION(0, 4, 4)
98 102
99static struct v4l2_queryctrl radio_qctrl[] = { 103static struct v4l2_queryctrl radio_qctrl[] = {
100 { 104 {
@@ -104,7 +108,27 @@ static struct v4l2_queryctrl radio_qctrl[] = {
104 .maximum = 1, 108 .maximum = 1,
105 .default_value = 1, 109 .default_value = 1,
106 .type = V4L2_CTRL_TYPE_BOOLEAN, 110 .type = V4L2_CTRL_TYPE_BOOLEAN,
107 } 111 },
112/* HINT: the disabled controls are only here to satify kradio and such apps */
113 { .id = V4L2_CID_AUDIO_VOLUME,
114 .flags = V4L2_CTRL_FLAG_DISABLED,
115 },
116 {
117 .id = V4L2_CID_AUDIO_BALANCE,
118 .flags = V4L2_CTRL_FLAG_DISABLED,
119 },
120 {
121 .id = V4L2_CID_AUDIO_BASS,
122 .flags = V4L2_CTRL_FLAG_DISABLED,
123 },
124 {
125 .id = V4L2_CID_AUDIO_TREBLE,
126 .flags = V4L2_CTRL_FLAG_DISABLED,
127 },
128 {
129 .id = V4L2_CID_AUDIO_LOUDNESS,
130 .flags = V4L2_CTRL_FLAG_DISABLED,
131 },
108}; 132};
109 133
110#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" 134#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
@@ -125,12 +149,16 @@ devices, that would be 76 and 91. */
125#define FREQ_MAX 108.0 149#define FREQ_MAX 108.0
126#define FREQ_MUL 16000 150#define FREQ_MUL 16000
127 151
152#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev)
128 153
129static int usb_dsbr100_probe(struct usb_interface *intf, 154static int usb_dsbr100_probe(struct usb_interface *intf,
130 const struct usb_device_id *id); 155 const struct usb_device_id *id);
131static void usb_dsbr100_disconnect(struct usb_interface *intf); 156static void usb_dsbr100_disconnect(struct usb_interface *intf);
132static int usb_dsbr100_open(struct inode *inode, struct file *file); 157static int usb_dsbr100_open(struct inode *inode, struct file *file);
133static int usb_dsbr100_close(struct inode *inode, struct file *file); 158static int usb_dsbr100_close(struct inode *inode, struct file *file);
159static int usb_dsbr100_suspend(struct usb_interface *intf,
160 pm_message_t message);
161static int usb_dsbr100_resume(struct usb_interface *intf);
134 162
135static int radio_nr = -1; 163static int radio_nr = -1;
136module_param(radio_nr, int, 0); 164module_param(radio_nr, int, 0);
@@ -138,8 +166,9 @@ module_param(radio_nr, int, 0);
138/* Data for one (physical) device */ 166/* Data for one (physical) device */
139struct dsbr100_device { 167struct dsbr100_device {
140 struct usb_device *usbdev; 168 struct usb_device *usbdev;
141 struct video_device *videodev; 169 struct video_device videodev;
142 u8 *transfer_buffer; 170 u8 *transfer_buffer;
171 struct mutex lock; /* buffer locking */
143 int curfreq; 172 int curfreq;
144 int stereo; 173 int stereo;
145 int users; 174 int users;
@@ -147,7 +176,6 @@ struct dsbr100_device {
147 int muted; 176 int muted;
148}; 177};
149 178
150
151static struct usb_device_id usb_dsbr100_device_table [] = { 179static struct usb_device_id usb_dsbr100_device_table [] = {
152 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) }, 180 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
153 { } /* Terminating entry */ 181 { } /* Terminating entry */
@@ -157,10 +185,14 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
157 185
158/* USB subsystem interface */ 186/* USB subsystem interface */
159static struct usb_driver usb_dsbr100_driver = { 187static struct usb_driver usb_dsbr100_driver = {
160 .name = "dsbr100", 188 .name = "dsbr100",
161 .probe = usb_dsbr100_probe, 189 .probe = usb_dsbr100_probe,
162 .disconnect = usb_dsbr100_disconnect, 190 .disconnect = usb_dsbr100_disconnect,
163 .id_table = usb_dsbr100_device_table, 191 .id_table = usb_dsbr100_device_table,
192 .suspend = usb_dsbr100_suspend,
193 .resume = usb_dsbr100_resume,
194 .reset_resume = usb_dsbr100_resume,
195 .supports_autosuspend = 0,
164}; 196};
165 197
166/* Low-level device interface begins here */ 198/* Low-level device interface begins here */
@@ -168,95 +200,190 @@ static struct usb_driver usb_dsbr100_driver = {
168/* switch on radio */ 200/* switch on radio */
169static int dsbr100_start(struct dsbr100_device *radio) 201static int dsbr100_start(struct dsbr100_device *radio)
170{ 202{
171 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 203 int retval;
172 USB_REQ_GET_STATUS, 204 int request;
173 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 205
174 0x00, 0xC7, radio->transfer_buffer, 8, 300) < 0 || 206 mutex_lock(&radio->lock);
175 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 207
176 DSB100_ONOFF, 208 retval = usb_control_msg(radio->usbdev,
177 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 209 usb_rcvctrlpipe(radio->usbdev, 0),
178 0x01, 0x00, radio->transfer_buffer, 8, 300) < 0) 210 USB_REQ_GET_STATUS,
179 return -1; 211 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
180 radio->muted=0; 212 0x00, 0xC7, radio->transfer_buffer, 8, 300);
213
214 if (retval < 0) {
215 request = USB_REQ_GET_STATUS;
216 goto usb_control_msg_failed;
217 }
218
219 retval = usb_control_msg(radio->usbdev,
220 usb_rcvctrlpipe(radio->usbdev, 0),
221 DSB100_ONOFF,
222 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
223 0x01, 0x00, radio->transfer_buffer, 8, 300);
224
225 if (retval < 0) {
226 request = DSB100_ONOFF;
227 goto usb_control_msg_failed;
228 }
229
230 radio->muted = 0;
231 mutex_unlock(&radio->lock);
181 return (radio->transfer_buffer)[0]; 232 return (radio->transfer_buffer)[0];
182}
183 233
234usb_control_msg_failed:
235 mutex_unlock(&radio->lock);
236 dev_err(&radio->usbdev->dev,
237 "%s - usb_control_msg returned %i, request %i\n",
238 __func__, retval, request);
239 return retval;
240
241}
184 242
185/* switch off radio */ 243/* switch off radio */
186static int dsbr100_stop(struct dsbr100_device *radio) 244static int dsbr100_stop(struct dsbr100_device *radio)
187{ 245{
188 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 246 int retval;
189 USB_REQ_GET_STATUS, 247 int request;
190 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 248
191 0x16, 0x1C, radio->transfer_buffer, 8, 300) < 0 || 249 mutex_lock(&radio->lock);
192 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 250
193 DSB100_ONOFF, 251 retval = usb_control_msg(radio->usbdev,
194 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 252 usb_rcvctrlpipe(radio->usbdev, 0),
195 0x00, 0x00, radio->transfer_buffer, 8, 300) < 0) 253 USB_REQ_GET_STATUS,
196 return -1; 254 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
197 radio->muted=1; 255 0x16, 0x1C, radio->transfer_buffer, 8, 300);
256
257 if (retval < 0) {
258 request = USB_REQ_GET_STATUS;
259 goto usb_control_msg_failed;
260 }
261
262 retval = usb_control_msg(radio->usbdev,
263 usb_rcvctrlpipe(radio->usbdev, 0),
264 DSB100_ONOFF,
265 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
266 0x00, 0x00, radio->transfer_buffer, 8, 300);
267
268 if (retval < 0) {
269 request = DSB100_ONOFF;
270 goto usb_control_msg_failed;
271 }
272
273 radio->muted = 1;
274 mutex_unlock(&radio->lock);
198 return (radio->transfer_buffer)[0]; 275 return (radio->transfer_buffer)[0];
276
277usb_control_msg_failed:
278 mutex_unlock(&radio->lock);
279 dev_err(&radio->usbdev->dev,
280 "%s - usb_control_msg returned %i, request %i\n",
281 __func__, retval, request);
282 return retval;
283
199} 284}
200 285
201/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ 286/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
202static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) 287static int dsbr100_setfreq(struct dsbr100_device *radio, int freq)
203{ 288{
289 int retval;
290 int request;
291
204 freq = (freq / 16 * 80) / 1000 + 856; 292 freq = (freq / 16 * 80) / 1000 + 856;
205 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 293 mutex_lock(&radio->lock);
206 DSB100_TUNE, 294
207 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 295 retval = usb_control_msg(radio->usbdev,
208 (freq >> 8) & 0x00ff, freq & 0xff, 296 usb_rcvctrlpipe(radio->usbdev, 0),
209 radio->transfer_buffer, 8, 300) < 0 || 297 DSB100_TUNE,
210 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 298 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
211 USB_REQ_GET_STATUS, 299 (freq >> 8) & 0x00ff, freq & 0xff,
212 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 300 radio->transfer_buffer, 8, 300);
213 0x96, 0xB7, radio->transfer_buffer, 8, 300) < 0 || 301
214 usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 302 if (retval < 0) {
215 USB_REQ_GET_STATUS, 303 request = DSB100_TUNE;
216 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 304 goto usb_control_msg_failed;
217 0x00, 0x24, radio->transfer_buffer, 8, 300) < 0) {
218 radio->stereo = -1;
219 return -1;
220 } 305 }
306
307 retval = usb_control_msg(radio->usbdev,
308 usb_rcvctrlpipe(radio->usbdev, 0),
309 USB_REQ_GET_STATUS,
310 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
311 0x96, 0xB7, radio->transfer_buffer, 8, 300);
312
313 if (retval < 0) {
314 request = USB_REQ_GET_STATUS;
315 goto usb_control_msg_failed;
316 }
317
318 retval = usb_control_msg(radio->usbdev,
319 usb_rcvctrlpipe(radio->usbdev, 0),
320 USB_REQ_GET_STATUS,
321 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
322 0x00, 0x24, radio->transfer_buffer, 8, 300);
323
324 if (retval < 0) {
325 request = USB_REQ_GET_STATUS;
326 goto usb_control_msg_failed;
327 }
328
221 radio->stereo = !((radio->transfer_buffer)[0] & 0x01); 329 radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
330 mutex_unlock(&radio->lock);
222 return (radio->transfer_buffer)[0]; 331 return (radio->transfer_buffer)[0];
332
333usb_control_msg_failed:
334 radio->stereo = -1;
335 mutex_unlock(&radio->lock);
336 dev_err(&radio->usbdev->dev,
337 "%s - usb_control_msg returned %i, request %i\n",
338 __func__, retval, request);
339 return retval;
223} 340}
224 341
225/* return the device status. This is, in effect, just whether it 342/* return the device status. This is, in effect, just whether it
226sees a stereo signal or not. Pity. */ 343sees a stereo signal or not. Pity. */
227static void dsbr100_getstat(struct dsbr100_device *radio) 344static void dsbr100_getstat(struct dsbr100_device *radio)
228{ 345{
229 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 346 int retval;
347
348 mutex_lock(&radio->lock);
349
350 retval = usb_control_msg(radio->usbdev,
351 usb_rcvctrlpipe(radio->usbdev, 0),
230 USB_REQ_GET_STATUS, 352 USB_REQ_GET_STATUS,
231 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 353 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
232 0x00 , 0x24, radio->transfer_buffer, 8, 300) < 0) 354 0x00 , 0x24, radio->transfer_buffer, 8, 300);
355
356 if (retval < 0) {
233 radio->stereo = -1; 357 radio->stereo = -1;
234 else 358 dev_err(&radio->usbdev->dev,
359 "%s - usb_control_msg returned %i, request %i\n",
360 __func__, retval, USB_REQ_GET_STATUS);
361 } else {
235 radio->stereo = !(radio->transfer_buffer[0] & 0x01); 362 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
236} 363 }
237 364
365 mutex_unlock(&radio->lock);
366}
238 367
239/* USB subsystem interface begins here */ 368/* USB subsystem interface begins here */
240 369
241/* handle unplugging of the device, release data structures 370/*
242if nothing keeps us from doing it. If something is still 371 * Handle unplugging of the device.
243keeping us busy, the release callback of v4l will take care 372 * We call video_unregister_device in any case.
244of releasing it. */ 373 * The last function called in this procedure is
374 * usb_dsbr100_video_device_release
375 */
245static void usb_dsbr100_disconnect(struct usb_interface *intf) 376static void usb_dsbr100_disconnect(struct usb_interface *intf)
246{ 377{
247 struct dsbr100_device *radio = usb_get_intfdata(intf); 378 struct dsbr100_device *radio = usb_get_intfdata(intf);
248 379
249 usb_set_intfdata (intf, NULL); 380 usb_set_intfdata (intf, NULL);
250 if (radio) { 381
251 video_unregister_device(radio->videodev); 382 mutex_lock(&radio->lock);
252 radio->videodev = NULL; 383 radio->removed = 1;
253 if (radio->users) { 384 mutex_unlock(&radio->lock);
254 kfree(radio->transfer_buffer); 385
255 kfree(radio); 386 video_unregister_device(&radio->videodev);
256 } else {
257 radio->removed = 1;
258 }
259 }
260} 387}
261 388
262 389
@@ -276,6 +403,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
276{ 403{
277 struct dsbr100_device *radio = video_drvdata(file); 404 struct dsbr100_device *radio = video_drvdata(file);
278 405
406 /* safety check */
407 if (radio->removed)
408 return -EIO;
409
279 if (v->index > 0) 410 if (v->index > 0)
280 return -EINVAL; 411 return -EINVAL;
281 412
@@ -297,6 +428,12 @@ static int vidioc_g_tuner(struct file *file, void *priv,
297static int vidioc_s_tuner(struct file *file, void *priv, 428static int vidioc_s_tuner(struct file *file, void *priv,
298 struct v4l2_tuner *v) 429 struct v4l2_tuner *v)
299{ 430{
431 struct dsbr100_device *radio = video_drvdata(file);
432
433 /* safety check */
434 if (radio->removed)
435 return -EIO;
436
300 if (v->index > 0) 437 if (v->index > 0)
301 return -EINVAL; 438 return -EINVAL;
302 439
@@ -307,9 +444,15 @@ static int vidioc_s_frequency(struct file *file, void *priv,
307 struct v4l2_frequency *f) 444 struct v4l2_frequency *f)
308{ 445{
309 struct dsbr100_device *radio = video_drvdata(file); 446 struct dsbr100_device *radio = video_drvdata(file);
447 int retval;
448
449 /* safety check */
450 if (radio->removed)
451 return -EIO;
310 452
311 radio->curfreq = f->frequency; 453 radio->curfreq = f->frequency;
312 if (dsbr100_setfreq(radio, radio->curfreq) == -1) 454 retval = dsbr100_setfreq(radio, radio->curfreq);
455 if (retval < 0)
313 dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); 456 dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
314 return 0; 457 return 0;
315} 458}
@@ -319,6 +462,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
319{ 462{
320 struct dsbr100_device *radio = video_drvdata(file); 463 struct dsbr100_device *radio = video_drvdata(file);
321 464
465 /* safety check */
466 if (radio->removed)
467 return -EIO;
468
322 f->type = V4L2_TUNER_RADIO; 469 f->type = V4L2_TUNER_RADIO;
323 f->frequency = radio->curfreq; 470 f->frequency = radio->curfreq;
324 return 0; 471 return 0;
@@ -343,6 +490,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
343{ 490{
344 struct dsbr100_device *radio = video_drvdata(file); 491 struct dsbr100_device *radio = video_drvdata(file);
345 492
493 /* safety check */
494 if (radio->removed)
495 return -EIO;
496
346 switch (ctrl->id) { 497 switch (ctrl->id) {
347 case V4L2_CID_AUDIO_MUTE: 498 case V4L2_CID_AUDIO_MUTE:
348 ctrl->value = radio->muted; 499 ctrl->value = radio->muted;
@@ -355,17 +506,24 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
355 struct v4l2_control *ctrl) 506 struct v4l2_control *ctrl)
356{ 507{
357 struct dsbr100_device *radio = video_drvdata(file); 508 struct dsbr100_device *radio = video_drvdata(file);
509 int retval;
510
511 /* safety check */
512 if (radio->removed)
513 return -EIO;
358 514
359 switch (ctrl->id) { 515 switch (ctrl->id) {
360 case V4L2_CID_AUDIO_MUTE: 516 case V4L2_CID_AUDIO_MUTE:
361 if (ctrl->value) { 517 if (ctrl->value) {
362 if (dsbr100_stop(radio) == -1) { 518 retval = dsbr100_stop(radio);
519 if (retval < 0) {
363 dev_warn(&radio->usbdev->dev, 520 dev_warn(&radio->usbdev->dev,
364 "Radio did not respond properly\n"); 521 "Radio did not respond properly\n");
365 return -EBUSY; 522 return -EBUSY;
366 } 523 }
367 } else { 524 } else {
368 if (dsbr100_start(radio) == -1) { 525 retval = dsbr100_start(radio);
526 if (retval < 0) {
369 dev_warn(&radio->usbdev->dev, 527 dev_warn(&radio->usbdev->dev,
370 "Radio did not respond properly\n"); 528 "Radio did not respond properly\n");
371 return -EBUSY; 529 return -EBUSY;
@@ -417,7 +575,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
417 radio->users = 1; 575 radio->users = 1;
418 radio->muted = 1; 576 radio->muted = 1;
419 577
420 if (dsbr100_start(radio) < 0) { 578 retval = dsbr100_start(radio);
579 if (retval < 0) {
421 dev_warn(&radio->usbdev->dev, 580 dev_warn(&radio->usbdev->dev,
422 "Radio did not start up properly\n"); 581 "Radio did not start up properly\n");
423 radio->users = 0; 582 radio->users = 0;
@@ -426,9 +585,9 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
426 } 585 }
427 586
428 retval = dsbr100_setfreq(radio, radio->curfreq); 587 retval = dsbr100_setfreq(radio, radio->curfreq);
429 588 if (retval < 0)
430 if (retval == -1) 589 dev_warn(&radio->usbdev->dev,
431 printk(KERN_WARNING KBUILD_MODNAME ": Set frequency failed\n"); 590 "set frequency failed\n");
432 591
433 unlock_kernel(); 592 unlock_kernel();
434 return 0; 593 return 0;
@@ -437,17 +596,62 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
437static int usb_dsbr100_close(struct inode *inode, struct file *file) 596static int usb_dsbr100_close(struct inode *inode, struct file *file)
438{ 597{
439 struct dsbr100_device *radio = video_drvdata(file); 598 struct dsbr100_device *radio = video_drvdata(file);
599 int retval;
440 600
441 if (!radio) 601 if (!radio)
442 return -ENODEV; 602 return -ENODEV;
603
443 radio->users = 0; 604 radio->users = 0;
444 if (radio->removed) { 605 if (!radio->removed) {
445 kfree(radio->transfer_buffer); 606 retval = dsbr100_stop(radio);
446 kfree(radio); 607 if (retval < 0) {
608 dev_warn(&radio->usbdev->dev,
609 "dsbr100_stop failed\n");
610 }
611
447 } 612 }
448 return 0; 613 return 0;
449} 614}
450 615
616/* Suspend device - stop device. */
617static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
618{
619 struct dsbr100_device *radio = usb_get_intfdata(intf);
620 int retval;
621
622 retval = dsbr100_stop(radio);
623 if (retval < 0)
624 dev_warn(&intf->dev, "dsbr100_stop failed\n");
625
626 dev_info(&intf->dev, "going into suspend..\n");
627
628 return 0;
629}
630
631/* Resume device - start device. */
632static int usb_dsbr100_resume(struct usb_interface *intf)
633{
634 struct dsbr100_device *radio = usb_get_intfdata(intf);
635 int retval;
636
637 retval = dsbr100_start(radio);
638 if (retval < 0)
639 dev_warn(&intf->dev, "dsbr100_start failed\n");
640
641 dev_info(&intf->dev, "coming out of suspend..\n");
642
643 return 0;
644}
645
646/* free data structures */
647static void usb_dsbr100_video_device_release(struct video_device *videodev)
648{
649 struct dsbr100_device *radio = videodev_to_radio(videodev);
650
651 kfree(radio->transfer_buffer);
652 kfree(radio);
653}
654
451/* File system interface */ 655/* File system interface */
452static const struct file_operations usb_dsbr100_fops = { 656static const struct file_operations usb_dsbr100_fops = {
453 .owner = THIS_MODULE, 657 .owner = THIS_MODULE,
@@ -476,19 +680,19 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
476}; 680};
477 681
478/* V4L2 interface */ 682/* V4L2 interface */
479static struct video_device dsbr100_videodev_template = { 683static struct video_device dsbr100_videodev_data = {
480 .name = "D-Link DSB-R 100", 684 .name = "D-Link DSB-R 100",
481 .fops = &usb_dsbr100_fops, 685 .fops = &usb_dsbr100_fops,
482 .ioctl_ops = &usb_dsbr100_ioctl_ops, 686 .ioctl_ops = &usb_dsbr100_ioctl_ops,
483 .release = video_device_release, 687 .release = usb_dsbr100_video_device_release,
484}; 688};
485 689
486/* check if the device is present and register with v4l and 690/* check if the device is present and register with v4l and usb if it is */
487usb if it is */
488static int usb_dsbr100_probe(struct usb_interface *intf, 691static int usb_dsbr100_probe(struct usb_interface *intf,
489 const struct usb_device_id *id) 692 const struct usb_device_id *id)
490{ 693{
491 struct dsbr100_device *radio; 694 struct dsbr100_device *radio;
695 int retval;
492 696
493 radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL); 697 radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
494 698
@@ -501,23 +705,18 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
501 kfree(radio); 705 kfree(radio);
502 return -ENOMEM; 706 return -ENOMEM;
503 } 707 }
504 radio->videodev = video_device_alloc();
505 708
506 if (!(radio->videodev)) { 709 mutex_init(&radio->lock);
507 kfree(radio->transfer_buffer); 710 radio->videodev = dsbr100_videodev_data;
508 kfree(radio); 711
509 return -ENOMEM;
510 }
511 memcpy(radio->videodev, &dsbr100_videodev_template,
512 sizeof(dsbr100_videodev_template));
513 radio->removed = 0; 712 radio->removed = 0;
514 radio->users = 0; 713 radio->users = 0;
515 radio->usbdev = interface_to_usbdev(intf); 714 radio->usbdev = interface_to_usbdev(intf);
516 radio->curfreq = FREQ_MIN * FREQ_MUL; 715 radio->curfreq = FREQ_MIN * FREQ_MUL;
517 video_set_drvdata(radio->videodev, radio); 716 video_set_drvdata(&radio->videodev, radio);
518 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) { 717 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
519 dev_warn(&intf->dev, "Could not register video device\n"); 718 if (retval < 0) {
520 video_device_release(radio->videodev); 719 dev_err(&intf->dev, "couldn't register video device\n");
521 kfree(radio->transfer_buffer); 720 kfree(radio->transfer_buffer);
522 kfree(radio); 721 kfree(radio);
523 return -EIO; 722 return -EIO;