diff options
Diffstat (limited to 'drivers/media/radio/radio-zoltrix.c')
-rw-r--r-- | drivers/media/radio/radio-zoltrix.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 51d57ed3b3e1..15b10bad6796 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
@@ -69,6 +69,7 @@ static int io = CONFIG_RADIO_ZOLTRIX_PORT; | |||
69 | static int radio_nr = -1; | 69 | static int radio_nr = -1; |
70 | 70 | ||
71 | struct zol_device { | 71 | struct zol_device { |
72 | unsigned long in_use; | ||
72 | int port; | 73 | int port; |
73 | int curvol; | 74 | int curvol; |
74 | unsigned long curfreq; | 75 | unsigned long curfreq; |
@@ -122,8 +123,11 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) | |||
122 | unsigned int stereo = dev->stereo; | 123 | unsigned int stereo = dev->stereo; |
123 | int i; | 124 | int i; |
124 | 125 | ||
125 | if (freq == 0) | 126 | if (freq == 0) { |
126 | return 1; | 127 | printk(KERN_WARNING "zoltrix: received zero freq. Failed to set.\n"); |
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
127 | m = (freq / 160 - 8800) * 2; | 131 | m = (freq / 160 - 8800) * 2; |
128 | f = (unsigned long long) m + 0x4d1c; | 132 | f = (unsigned long long) m + 0x4d1c; |
129 | 133 | ||
@@ -245,8 +249,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
245 | static int vidioc_g_tuner(struct file *file, void *priv, | 249 | static int vidioc_g_tuner(struct file *file, void *priv, |
246 | struct v4l2_tuner *v) | 250 | struct v4l2_tuner *v) |
247 | { | 251 | { |
248 | struct video_device *dev = video_devdata(file); | 252 | struct zol_device *zol = video_drvdata(file); |
249 | struct zol_device *zol = dev->priv; | ||
250 | 253 | ||
251 | if (v->index > 0) | 254 | if (v->index > 0) |
252 | return -EINVAL; | 255 | return -EINVAL; |
@@ -276,19 +279,20 @@ static int vidioc_s_tuner(struct file *file, void *priv, | |||
276 | static int vidioc_s_frequency(struct file *file, void *priv, | 279 | static int vidioc_s_frequency(struct file *file, void *priv, |
277 | struct v4l2_frequency *f) | 280 | struct v4l2_frequency *f) |
278 | { | 281 | { |
279 | struct video_device *dev = video_devdata(file); | 282 | struct zol_device *zol = video_drvdata(file); |
280 | struct zol_device *zol = dev->priv; | ||
281 | 283 | ||
282 | zol->curfreq = f->frequency; | 284 | zol->curfreq = f->frequency; |
283 | zol_setfreq(zol, zol->curfreq); | 285 | if (zol_setfreq(zol, zol->curfreq) != 0) { |
286 | printk(KERN_WARNING "zoltrix: Set frequency failed.\n"); | ||
287 | return -EINVAL; | ||
288 | } | ||
284 | return 0; | 289 | return 0; |
285 | } | 290 | } |
286 | 291 | ||
287 | static int vidioc_g_frequency(struct file *file, void *priv, | 292 | static int vidioc_g_frequency(struct file *file, void *priv, |
288 | struct v4l2_frequency *f) | 293 | struct v4l2_frequency *f) |
289 | { | 294 | { |
290 | struct video_device *dev = video_devdata(file); | 295 | struct zol_device *zol = video_drvdata(file); |
291 | struct zol_device *zol = dev->priv; | ||
292 | 296 | ||
293 | f->type = V4L2_TUNER_RADIO; | 297 | f->type = V4L2_TUNER_RADIO; |
294 | f->frequency = zol->curfreq; | 298 | f->frequency = zol->curfreq; |
@@ -313,8 +317,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
313 | static int vidioc_g_ctrl(struct file *file, void *priv, | 317 | static int vidioc_g_ctrl(struct file *file, void *priv, |
314 | struct v4l2_control *ctrl) | 318 | struct v4l2_control *ctrl) |
315 | { | 319 | { |
316 | struct video_device *dev = video_devdata(file); | 320 | struct zol_device *zol = video_drvdata(file); |
317 | struct zol_device *zol = dev->priv; | ||
318 | 321 | ||
319 | switch (ctrl->id) { | 322 | switch (ctrl->id) { |
320 | case V4L2_CID_AUDIO_MUTE: | 323 | case V4L2_CID_AUDIO_MUTE: |
@@ -330,8 +333,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
330 | static int vidioc_s_ctrl(struct file *file, void *priv, | 333 | static int vidioc_s_ctrl(struct file *file, void *priv, |
331 | struct v4l2_control *ctrl) | 334 | struct v4l2_control *ctrl) |
332 | { | 335 | { |
333 | struct video_device *dev = video_devdata(file); | 336 | struct zol_device *zol = video_drvdata(file); |
334 | struct zol_device *zol = dev->priv; | ||
335 | 337 | ||
336 | switch (ctrl->id) { | 338 | switch (ctrl->id) { |
337 | case V4L2_CID_AUDIO_MUTE: | 339 | case V4L2_CID_AUDIO_MUTE: |
@@ -347,7 +349,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
347 | return 0; | 349 | return 0; |
348 | } | 350 | } |
349 | zol->stereo = 1; | 351 | zol->stereo = 1; |
350 | zol_setfreq(zol, zol->curfreq); | 352 | if (zol_setfreq(zol, zol->curfreq) != 0) { |
353 | printk(KERN_WARNING "zoltrix: Set frequency failed.\n"); | ||
354 | return -EINVAL; | ||
355 | } | ||
351 | #if 0 | 356 | #if 0 |
352 | /* FIXME: Implement stereo/mono switch on V4L2 */ | 357 | /* FIXME: Implement stereo/mono switch on V4L2 */ |
353 | if (v->mode & VIDEO_SOUND_STEREO) { | 358 | if (v->mode & VIDEO_SOUND_STEREO) { |
@@ -396,11 +401,22 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
396 | 401 | ||
397 | static struct zol_device zoltrix_unit; | 402 | static struct zol_device zoltrix_unit; |
398 | 403 | ||
404 | static int zoltrix_exclusive_open(struct inode *inode, struct file *file) | ||
405 | { | ||
406 | return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0; | ||
407 | } | ||
408 | |||
409 | static int zoltrix_exclusive_release(struct inode *inode, struct file *file) | ||
410 | { | ||
411 | clear_bit(0, &zoltrix_unit.in_use); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
399 | static const struct file_operations zoltrix_fops = | 415 | static const struct file_operations zoltrix_fops = |
400 | { | 416 | { |
401 | .owner = THIS_MODULE, | 417 | .owner = THIS_MODULE, |
402 | .open = video_exclusive_open, | 418 | .open = zoltrix_exclusive_open, |
403 | .release = video_exclusive_release, | 419 | .release = zoltrix_exclusive_release, |
404 | .ioctl = video_ioctl2, | 420 | .ioctl = video_ioctl2, |
405 | #ifdef CONFIG_COMPAT | 421 | #ifdef CONFIG_COMPAT |
406 | .compat_ioctl = v4l_compat_ioctl32, | 422 | .compat_ioctl = v4l_compat_ioctl32, |
@@ -427,6 +443,7 @@ static struct video_device zoltrix_radio = { | |||
427 | .name = "Zoltrix Radio Plus", | 443 | .name = "Zoltrix Radio Plus", |
428 | .fops = &zoltrix_fops, | 444 | .fops = &zoltrix_fops, |
429 | .ioctl_ops = &zoltrix_ioctl_ops, | 445 | .ioctl_ops = &zoltrix_ioctl_ops, |
446 | .release = video_device_release_empty, | ||
430 | }; | 447 | }; |
431 | 448 | ||
432 | static int __init zoltrix_init(void) | 449 | static int __init zoltrix_init(void) |
@@ -440,7 +457,7 @@ static int __init zoltrix_init(void) | |||
440 | return -ENXIO; | 457 | return -ENXIO; |
441 | } | 458 | } |
442 | 459 | ||
443 | zoltrix_radio.priv = &zoltrix_unit; | 460 | video_set_drvdata(&zoltrix_radio, &zoltrix_unit); |
444 | if (!request_region(io, 2, "zoltrix")) { | 461 | if (!request_region(io, 2, "zoltrix")) { |
445 | printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io); | 462 | printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io); |
446 | return -EBUSY; | 463 | return -EBUSY; |