aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-sf16fmr2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/radio-sf16fmr2.c')
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c350
1 files changed, 190 insertions, 160 deletions
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index b96fafe1f9da..e6c125def5cb 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -226,186 +226,204 @@ static int fmr2_setvolume(struct fmr2_device *dev)
226 return 0; 226 return 0;
227} 227}
228 228
229static int fmr2_do_ioctl(struct inode *inode, struct file *file, 229static int vidioc_querycap(struct file *file, void *priv,
230 unsigned int cmd, void *arg) 230 struct v4l2_capability *v)
231{ 231{
232 strlcpy(v->driver, "radio-sf16fmr2", sizeof(v->driver));
233 strlcpy(v->card, "SF16-FMR2 radio", sizeof(v->card));
234 sprintf(v->bus_info, "ISA");
235 v->version = RADIO_VERSION;
236 v->capabilities = V4L2_CAP_TUNER;
237 return 0;
238}
239
240static int vidioc_g_tuner(struct file *file, void *priv,
241 struct v4l2_tuner *v)
242{
243 int mult;
232 struct video_device *dev = video_devdata(file); 244 struct video_device *dev = video_devdata(file);
233 struct fmr2_device *fmr2 = dev->priv; 245 struct fmr2_device *fmr2 = dev->priv;
234 debug_print((KERN_DEBUG "freq %ld flags %d vol %d mute %d "
235 "stereo %d type %d\n",
236 fmr2->curfreq, fmr2->flags, fmr2->curvol, fmr2->mute,
237 fmr2->stereo, fmr2->card_type));
238 246
239 switch(cmd) 247 if (v->index > 0)
240 { 248 return -EINVAL;
241 case VIDIOC_QUERYCAP:
242 {
243 struct v4l2_capability *v = arg;
244 memset(v,0,sizeof(*v));
245 strlcpy(v->driver, "radio-sf16fmr2", sizeof (v->driver));
246 strlcpy(v->card, "SF16-FMR2 radio", sizeof (v->card));
247 sprintf(v->bus_info,"ISA");
248 v->version = RADIO_VERSION;
249 v->capabilities = V4L2_CAP_TUNER;
250 249
251 return 0; 250 strcpy(v->name, "FM");
252 } 251 v->type = V4L2_TUNER_RADIO;
253 case VIDIOC_G_TUNER:
254 {
255 struct v4l2_tuner *v = arg;
256 int mult;
257
258 if (v->index > 0)
259 return -EINVAL;
260
261 memset(v,0,sizeof(*v));
262 strcpy(v->name, "FM");
263 v->type = V4L2_TUNER_RADIO;
264
265 mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
266 v->rangelow = RSF16_MINFREQ/mult;
267 v->rangehigh = RSF16_MAXFREQ/mult;
268 v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
269 v->capability=fmr2->flags&V4L2_TUNER_CAP_LOW;
270
271 v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
272 V4L2_TUNER_MODE_MONO;
273 mutex_lock(&lock);
274 v->signal = fmr2_getsigstr(fmr2);
275 mutex_unlock(&lock);
276 252
277 return 0; 253 mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
278 } 254 v->rangelow = RSF16_MINFREQ/mult;
279 case VIDIOC_S_TUNER: 255 v->rangehigh = RSF16_MAXFREQ/mult;
280 { 256 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
281 struct v4l2_tuner *v = arg; 257 v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW;
258 v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
259 V4L2_TUNER_MODE_MONO;
260 mutex_lock(&lock);
261 v->signal = fmr2_getsigstr(fmr2);
262 mutex_unlock(&lock);
263 return 0;
264}
282 265
283 if (v->index > 0) 266static int vidioc_s_tuner(struct file *file, void *priv,
284 return -EINVAL; 267 struct v4l2_tuner *v)
268{
269 if (v->index > 0)
270 return -EINVAL;
271 return 0;
272}
285 273
286 return 0; 274static int vidioc_s_frequency(struct file *file, void *priv,
287 } 275 struct v4l2_frequency *f)
288 case VIDIOC_S_FREQUENCY: 276{
289 { 277 struct video_device *dev = video_devdata(file);
290 struct v4l2_frequency *f = arg; 278 struct fmr2_device *fmr2 = dev->priv;
291
292 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
293 f->frequency *= 1000;
294 if (f->frequency < RSF16_MINFREQ ||
295 f->frequency > RSF16_MAXFREQ )
296 return -EINVAL;
297 /*rounding in steps of 200 to match th freq
298 that will be used */
299 fmr2->curfreq = (f->frequency/200)*200;
300
301 /* set card freq (if not muted) */
302 if (fmr2->curvol && !fmr2->mute)
303 {
304 mutex_lock(&lock);
305 fmr2_setfreq(fmr2);
306 mutex_unlock(&lock);
307 }
308 279
309 return 0; 280 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
310 } 281 f->frequency *= 1000;
311 case VIDIOC_G_FREQUENCY: 282 if (f->frequency < RSF16_MINFREQ ||
312 { 283 f->frequency > RSF16_MAXFREQ )
313 struct v4l2_frequency *f = arg; 284 return -EINVAL;
285 /*rounding in steps of 200 to match th freq
286 that will be used */
287 fmr2->curfreq = (f->frequency/200)*200;
288
289 /* set card freq (if not muted) */
290 if (fmr2->curvol && !fmr2->mute) {
291 mutex_lock(&lock);
292 fmr2_setfreq(fmr2);
293 mutex_unlock(&lock);
294 }
295 return 0;
296}
297
298static int vidioc_g_frequency(struct file *file, void *priv,
299 struct v4l2_frequency *f)
300{
301 struct video_device *dev = video_devdata(file);
302 struct fmr2_device *fmr2 = dev->priv;
314 303
315 f->type = V4L2_TUNER_RADIO; 304 f->type = V4L2_TUNER_RADIO;
316 f->frequency = fmr2->curfreq; 305 f->frequency = fmr2->curfreq;
317 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) 306 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
318 f->frequency /= 1000; 307 f->frequency /= 1000;
308 return 0;
309}
319 310
311static int vidioc_queryctrl(struct file *file, void *priv,
312 struct v4l2_queryctrl *qc)
313{
314 int i;
315 struct video_device *dev = video_devdata(file);
316 struct fmr2_device *fmr2 = dev->priv;
317
318 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
319 if ((fmr2->card_type != 11)
320 && V4L2_CID_AUDIO_VOLUME)
321 radio_qctrl[i].step = 65535;
322 if (qc->id && qc->id == radio_qctrl[i].id) {
323 memcpy(qc, &(radio_qctrl[i]),
324 sizeof(*qc));
320 return 0; 325 return 0;
321 } 326 }
322 case VIDIOC_QUERYCTRL: 327 }
323 { 328 return -EINVAL;
324 struct v4l2_queryctrl *qc = arg; 329}
325 int i; 330
326 331static int vidioc_g_ctrl(struct file *file, void *priv,
327 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 332 struct v4l2_control *ctrl)
328 if ((fmr2->card_type != 11) 333{
329 && V4L2_CID_AUDIO_VOLUME) 334 struct video_device *dev = video_devdata(file);
330 radio_qctrl[i].step=65535; 335 struct fmr2_device *fmr2 = dev->priv;
331 if (qc->id && qc->id == radio_qctrl[i].id) { 336
332 memcpy(qc, &(radio_qctrl[i]), 337 switch (ctrl->id) {
333 sizeof(*qc)); 338 case V4L2_CID_AUDIO_MUTE:
334 return (0); 339 ctrl->value = fmr2->mute;
335 } 340 return 0;
336 } 341 case V4L2_CID_AUDIO_VOLUME:
337 return -EINVAL; 342 ctrl->value = fmr2->curvol;
343 return 0;
344 }
345 return -EINVAL;
346}
347
348static int vidioc_s_ctrl(struct file *file, void *priv,
349 struct v4l2_control *ctrl)
350{
351 struct video_device *dev = video_devdata(file);
352 struct fmr2_device *fmr2 = dev->priv;
353
354 switch (ctrl->id) {
355 case V4L2_CID_AUDIO_MUTE:
356 fmr2->mute = ctrl->value;
357 if (fmr2->card_type != 11) {
358 if (!fmr2->mute)
359 fmr2->curvol = 65535;
360 else
361 fmr2->curvol = 0;
338 } 362 }
339 case VIDIOC_G_CTRL: 363 break;
340 { 364 case V4L2_CID_AUDIO_VOLUME:
341 struct v4l2_control *ctrl= arg; 365 fmr2->curvol = ctrl->value;
342 366 if (fmr2->card_type != 11) {
343 switch (ctrl->id) { 367 if (fmr2->curvol) {
344 case V4L2_CID_AUDIO_MUTE: 368 fmr2->curvol = 65535;
345 ctrl->value=fmr2->mute; 369 fmr2->mute = 0;
346 return (0); 370 } else {
347 case V4L2_CID_AUDIO_VOLUME: 371 fmr2->curvol = 0;
348 ctrl->value=fmr2->curvol; 372 fmr2->mute = 1;
349 return (0);
350 } 373 }
351 return -EINVAL;
352 } 374 }
353 case VIDIOC_S_CTRL: 375 break;
354 { 376 default:
355 struct v4l2_control *ctrl= arg; 377 return -EINVAL;
356 378 }
357 switch (ctrl->id) { 379
358 case V4L2_CID_AUDIO_MUTE:
359 fmr2->mute=ctrl->value;
360 if (fmr2->card_type != 11) {
361 if (!fmr2->mute) {
362 fmr2->curvol = 65535;
363 } else {
364 fmr2->curvol = 0;
365 }
366 }
367 break;
368 case V4L2_CID_AUDIO_VOLUME:
369 fmr2->curvol = ctrl->value;
370 if (fmr2->card_type != 11) {
371 if (fmr2->curvol) {
372 fmr2->curvol = 65535;
373 fmr2->mute = 0;
374 } else {
375 fmr2->curvol = 0;
376 fmr2->mute = 1;
377 }
378 }
379 break;
380 default:
381 return -EINVAL;
382 }
383#ifdef DEBUG 380#ifdef DEBUG
384 if (fmr2->curvol && !fmr2->mute) 381 if (fmr2->curvol && !fmr2->mute)
385 printk(KERN_DEBUG "unmute\n"); 382 printk(KERN_DEBUG "unmute\n");
386 else 383 else
387 printk(KERN_DEBUG "mute\n"); 384 printk(KERN_DEBUG "mute\n");
388#endif 385#endif
389 mutex_lock(&lock);
390 if (fmr2->curvol && !fmr2->mute) {
391 fmr2_setvolume(fmr2);
392 fmr2_setfreq(fmr2);
393 } else
394 fmr2_mute(fmr2->port);
395 mutex_unlock(&lock);
396 return (0);
397 }
398 default:
399 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
400 fmr2_do_ioctl);
401 386
402 } 387 mutex_lock(&lock);
388 if (fmr2->curvol && !fmr2->mute) {
389 fmr2_setvolume(fmr2);
390 fmr2_setfreq(fmr2);
391 } else
392 fmr2_mute(fmr2->port);
393 mutex_unlock(&lock);
394 return 0;
403} 395}
404 396
405static int fmr2_ioctl(struct inode *inode, struct file *file, 397static int vidioc_g_audio(struct file *file, void *priv,
406 unsigned int cmd, unsigned long arg) 398 struct v4l2_audio *a)
407 { 399{
408 return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl); 400 if (a->index > 1)
401 return -EINVAL;
402
403 strcpy(a->name, "Radio");
404 a->capability = V4L2_AUDCAP_STEREO;
405 return 0;
406}
407
408static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
409{
410 *i = 0;
411 return 0;
412}
413
414static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
415{
416 if (i != 0)
417 return -EINVAL;
418 return 0;
419}
420
421static int vidioc_s_audio(struct file *file, void *priv,
422 struct v4l2_audio *a)
423{
424 if (a->index != 0)
425 return -EINVAL;
426 return 0;
409} 427}
410 428
411static struct fmr2_device fmr2_unit; 429static struct fmr2_device fmr2_unit;
@@ -414,7 +432,7 @@ static const struct file_operations fmr2_fops = {
414 .owner = THIS_MODULE, 432 .owner = THIS_MODULE,
415 .open = video_exclusive_open, 433 .open = video_exclusive_open,
416 .release = video_exclusive_release, 434 .release = video_exclusive_release,
417 .ioctl = fmr2_ioctl, 435 .ioctl = video_ioctl2,
418 .compat_ioctl = v4l_compat_ioctl32, 436 .compat_ioctl = v4l_compat_ioctl32,
419 .llseek = no_llseek, 437 .llseek = no_llseek,
420}; 438};
@@ -426,6 +444,18 @@ static struct video_device fmr2_radio=
426 . type = VID_TYPE_TUNER, 444 . type = VID_TYPE_TUNER,
427 .hardware = 0, 445 .hardware = 0,
428 .fops = &fmr2_fops, 446 .fops = &fmr2_fops,
447 .vidioc_querycap = vidioc_querycap,
448 .vidioc_g_tuner = vidioc_g_tuner,
449 .vidioc_s_tuner = vidioc_s_tuner,
450 .vidioc_g_audio = vidioc_g_audio,
451 .vidioc_s_audio = vidioc_s_audio,
452 .vidioc_g_input = vidioc_g_input,
453 .vidioc_s_input = vidioc_s_input,
454 .vidioc_g_frequency = vidioc_g_frequency,
455 .vidioc_s_frequency = vidioc_s_frequency,
456 .vidioc_queryctrl = vidioc_queryctrl,
457 .vidioc_g_ctrl = vidioc_g_ctrl,
458 .vidioc_s_ctrl = vidioc_s_ctrl,
429}; 459};
430 460
431static int __init fmr2_init(void) 461static int __init fmr2_init(void)