aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-zoltrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/radio-zoltrix.c')
-rw-r--r--drivers/media/radio/radio-zoltrix.c51
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;
69static int radio_nr = -1; 69static int radio_nr = -1;
70 70
71struct zol_device { 71struct 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,
245static int vidioc_g_tuner(struct file *file, void *priv, 249static 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,
276static int vidioc_s_frequency(struct file *file, void *priv, 279static 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
287static int vidioc_g_frequency(struct file *file, void *priv, 292static 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,
313static int vidioc_g_ctrl(struct file *file, void *priv, 317static 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,
330static int vidioc_s_ctrl(struct file *file, void *priv, 333static 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
397static struct zol_device zoltrix_unit; 402static struct zol_device zoltrix_unit;
398 403
404static 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
409static int zoltrix_exclusive_release(struct inode *inode, struct file *file)
410{
411 clear_bit(0, &zoltrix_unit.in_use);
412 return 0;
413}
414
399static const struct file_operations zoltrix_fops = 415static 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
432static int __init zoltrix_init(void) 449static 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;