diff options
author | Mike Isely <isely@pobox.com> | 2006-06-25 19:04:40 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-26 23:17:27 -0400 |
commit | 332139635a8c0431cc2eb67adf1e983eb96728e3 (patch) | |
tree | e7646bc367486fd1b52bd80bc789fe26307ed9fe /drivers/media/video | |
parent | 077203a7d464f6ea7c94b4f3ea4b5bd246285fcd (diff) |
V4L/DVB (4239): Handle boolean controls in pvrusb2
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-ctrl.c | 33 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-ctrl.h | 1 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 16 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 39 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 6 |
5 files changed, 83 insertions, 12 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 3577d5bfa007..d644afec5a5c 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c | |||
@@ -53,6 +53,8 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) | |||
53 | if (val >= cptr->info->def.type_enum.count) { | 53 | if (val >= cptr->info->def.type_enum.count) { |
54 | break; | 54 | break; |
55 | } | 55 | } |
56 | } else if (cptr->info->type != pvr2_ctl_bool) { | ||
57 | break; | ||
56 | } | 58 | } |
57 | ret = cptr->info->set_value(cptr,mask,val); | 59 | ret = cptr->info->set_value(cptr,mask,val); |
58 | } else { | 60 | } else { |
@@ -308,6 +310,14 @@ static unsigned int gen_bitmask_string(int msk,int val,int msk_only, | |||
308 | } | 310 | } |
309 | 311 | ||
310 | 312 | ||
313 | static const char *boolNames[] = { | ||
314 | "false", | ||
315 | "true", | ||
316 | "no", | ||
317 | "yes", | ||
318 | }; | ||
319 | |||
320 | |||
311 | static int parse_token(const char *ptr,unsigned int len, | 321 | static int parse_token(const char *ptr,unsigned int len, |
312 | int *valptr, | 322 | int *valptr, |
313 | const char **names,unsigned int namecnt) | 323 | const char **names,unsigned int namecnt) |
@@ -338,7 +348,7 @@ static int parse_token(const char *ptr,unsigned int len, | |||
338 | *valptr = simple_strtol(buf,&p2,0); | 348 | *valptr = simple_strtol(buf,&p2,0); |
339 | if (negfl) *valptr = -(*valptr); | 349 | if (negfl) *valptr = -(*valptr); |
340 | if (*p2) return -EINVAL; | 350 | if (*p2) return -EINVAL; |
341 | return 0; | 351 | return 1; |
342 | } | 352 | } |
343 | 353 | ||
344 | 354 | ||
@@ -453,21 +463,31 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, | |||
453 | LOCK_TAKE(cptr->hdw->big_lock); do { | 463 | LOCK_TAKE(cptr->hdw->big_lock); do { |
454 | if (cptr->info->type == pvr2_ctl_int) { | 464 | if (cptr->info->type == pvr2_ctl_int) { |
455 | ret = parse_token(ptr,len,valptr,0,0); | 465 | ret = parse_token(ptr,len,valptr,0,0); |
456 | if ((ret == 0) && | 466 | if ((ret >= 0) && |
457 | ((*valptr < cptr->info->def.type_int.min_value) || | 467 | ((*valptr < cptr->info->def.type_int.min_value) || |
458 | (*valptr > cptr->info->def.type_int.max_value))) { | 468 | (*valptr > cptr->info->def.type_int.max_value))) { |
459 | ret = -EINVAL; | 469 | ret = -ERANGE; |
460 | } | 470 | } |
461 | if (maskptr) *maskptr = ~0; | 471 | if (maskptr) *maskptr = ~0; |
472 | } else if (cptr->info->type == pvr2_ctl_bool) { | ||
473 | ret = parse_token( | ||
474 | ptr,len,valptr,boolNames, | ||
475 | sizeof(boolNames)/sizeof(boolNames[0])); | ||
476 | if (ret == 1) { | ||
477 | *valptr = *valptr ? !0 : 0; | ||
478 | } else if (ret == 0) { | ||
479 | *valptr = (*valptr & 1) ? !0 : 0; | ||
480 | } | ||
481 | if (maskptr) *maskptr = 1; | ||
462 | } else if (cptr->info->type == pvr2_ctl_enum) { | 482 | } else if (cptr->info->type == pvr2_ctl_enum) { |
463 | ret = parse_token( | 483 | ret = parse_token( |
464 | ptr,len,valptr, | 484 | ptr,len,valptr, |
465 | cptr->info->def.type_enum.value_names, | 485 | cptr->info->def.type_enum.value_names, |
466 | cptr->info->def.type_enum.count); | 486 | cptr->info->def.type_enum.count); |
467 | if ((ret == 0) && | 487 | if ((ret >= 0) && |
468 | ((*valptr < 0) || | 488 | ((*valptr < 0) || |
469 | (*valptr >= cptr->info->def.type_enum.count))) { | 489 | (*valptr >= cptr->info->def.type_enum.count))) { |
470 | ret = -EINVAL; | 490 | ret = -ERANGE; |
471 | } | 491 | } |
472 | if (maskptr) *maskptr = ~0; | 492 | if (maskptr) *maskptr = ~0; |
473 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | 493 | } else if (cptr->info->type == pvr2_ctl_bitmask) { |
@@ -493,6 +513,9 @@ int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr, | |||
493 | if (cptr->info->type == pvr2_ctl_int) { | 513 | if (cptr->info->type == pvr2_ctl_int) { |
494 | *len = scnprintf(buf,maxlen,"%d",val); | 514 | *len = scnprintf(buf,maxlen,"%d",val); |
495 | ret = 0; | 515 | ret = 0; |
516 | } else if (cptr->info->type == pvr2_ctl_bool) { | ||
517 | *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); | ||
518 | ret = 0; | ||
496 | } else if (cptr->info->type == pvr2_ctl_enum) { | 519 | } else if (cptr->info->type == pvr2_ctl_enum) { |
497 | const char **names; | 520 | const char **names; |
498 | names = cptr->info->def.type_enum.value_names; | 521 | names = cptr->info->def.type_enum.value_names; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h index 9d74151a37da..bf4cf65441fb 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h | |||
@@ -27,6 +27,7 @@ enum pvr2_ctl_type { | |||
27 | pvr2_ctl_int = 0, | 27 | pvr2_ctl_int = 0, |
28 | pvr2_ctl_enum = 1, | 28 | pvr2_ctl_enum = 1, |
29 | pvr2_ctl_bitmask = 2, | 29 | pvr2_ctl_bitmask = 2, |
30 | pvr2_ctl_bool = 3, | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | 33 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 872705633048..7d46bc10179a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -436,6 +436,9 @@ static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr) | |||
436 | .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \ | 436 | .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \ |
437 | .def.type_enum.value_names = tab | 437 | .def.type_enum.value_names = tab |
438 | 438 | ||
439 | #define DEFBOOL \ | ||
440 | .type = pvr2_ctl_bool | ||
441 | |||
439 | #define DEFMASK(msk,tab) \ | 442 | #define DEFMASK(msk,tab) \ |
440 | .type = pvr2_ctl_bitmask, \ | 443 | .type = pvr2_ctl_bitmask, \ |
441 | .def.type_bitmask.valid_bits = msk, \ | 444 | .def.type_bitmask.valid_bits = msk, \ |
@@ -548,7 +551,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
548 | .name = "mute", | 551 | .name = "mute", |
549 | .default_value = 0, | 552 | .default_value = 0, |
550 | DEFREF(mute), | 553 | DEFREF(mute), |
551 | DEFINT(0,1), | 554 | DEFBOOL, |
552 | },{ | 555 | },{ |
553 | .desc = "Video Source", | 556 | .desc = "Video Source", |
554 | .name = "input", | 557 | .name = "input", |
@@ -597,7 +600,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
597 | .name = "audio_crc", | 600 | .name = "audio_crc", |
598 | .default_value = 1, | 601 | .default_value = 1, |
599 | DEFREF(audiocrc), | 602 | DEFREF(audiocrc), |
600 | DEFINT(0,1), | 603 | DEFBOOL, |
601 | },{ | 604 | },{ |
602 | .v4l_id = V4L2_CID_PVR_AUDIOEMPHASIS, | 605 | .v4l_id = V4L2_CID_PVR_AUDIOEMPHASIS, |
603 | .desc = "Audio Emphasis", | 606 | .desc = "Audio Emphasis", |
@@ -611,7 +614,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
611 | .name = "vbr", | 614 | .name = "vbr", |
612 | .default_value = 0, | 615 | .default_value = 0, |
613 | DEFREF(vbr), | 616 | DEFREF(vbr), |
614 | DEFINT(0,1), | 617 | DEFBOOL, |
615 | },{ | 618 | },{ |
616 | .v4l_id = V4L2_CID_PVR_VIDEOBITRATE, | 619 | .v4l_id = V4L2_CID_PVR_VIDEOBITRATE, |
617 | .desc = "Average video bitrate", | 620 | .desc = "Average video bitrate", |
@@ -632,7 +635,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
632 | .internal_id = PVR2_CID_INTERLACE, | 635 | .internal_id = PVR2_CID_INTERLACE, |
633 | .default_value = 0, | 636 | .default_value = 0, |
634 | DEFREF(interlace), | 637 | DEFREF(interlace), |
635 | DEFINT(0,1), | 638 | DEFBOOL, |
636 | },{ | 639 | },{ |
637 | .desc = "Audio Layer", | 640 | .desc = "Audio Layer", |
638 | .name = "audio_layer", | 641 | .name = "audio_layer", |
@@ -671,7 +674,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
671 | .desc = "Streaming Enabled", | 674 | .desc = "Streaming Enabled", |
672 | .name = "streaming_enabled", | 675 | .name = "streaming_enabled", |
673 | .get_value = ctrl_streamingenabled_get, | 676 | .get_value = ctrl_streamingenabled_get, |
674 | DEFINT(0,1), | 677 | DEFBOOL, |
675 | },{ | 678 | },{ |
676 | .desc = "USB Speed", | 679 | .desc = "USB Speed", |
677 | .name = "usb_speed", | 680 | .name = "usb_speed", |
@@ -681,7 +684,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
681 | .desc = "Signal Present", | 684 | .desc = "Signal Present", |
682 | .name = "signal_present", | 685 | .name = "signal_present", |
683 | .get_value = ctrl_signal_get, | 686 | .get_value = ctrl_signal_get, |
684 | DEFINT(0,1), | 687 | DEFBOOL, |
685 | },{ | 688 | },{ |
686 | .desc = "Video Standards Available Mask", | 689 | .desc = "Video Standards Available Mask", |
687 | .name = "video_standard_mask_available", | 690 | .name = "video_standard_mask_available", |
@@ -2007,6 +2010,7 @@ static const char *get_ctrl_typename(enum pvr2_ctl_type tp) | |||
2007 | switch (tp) { | 2010 | switch (tp) { |
2008 | case pvr2_ctl_int: return "integer"; | 2011 | case pvr2_ctl_int: return "integer"; |
2009 | case pvr2_ctl_enum: return "enum"; | 2012 | case pvr2_ctl_enum: return "enum"; |
2013 | case pvr2_ctl_bool: return "boolean"; | ||
2010 | case pvr2_ctl_bitmask: return "bitmask"; | 2014 | case pvr2_ctl_bitmask: return "bitmask"; |
2011 | } | 2015 | } |
2012 | return ""; | 2016 | return ""; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 42540627e30d..c6e6523d74b4 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -55,6 +55,7 @@ struct pvr2_sysfs_debugifc { | |||
55 | 55 | ||
56 | struct pvr2_sysfs_ctl_item { | 56 | struct pvr2_sysfs_ctl_item { |
57 | struct class_device_attribute attr_name; | 57 | struct class_device_attribute attr_name; |
58 | struct class_device_attribute attr_type; | ||
58 | struct class_device_attribute attr_min; | 59 | struct class_device_attribute attr_min; |
59 | struct class_device_attribute attr_max; | 60 | struct class_device_attribute attr_max; |
60 | struct class_device_attribute attr_enum; | 61 | struct class_device_attribute attr_enum; |
@@ -64,7 +65,7 @@ struct pvr2_sysfs_ctl_item { | |||
64 | struct pvr2_ctrl *cptr; | 65 | struct pvr2_ctrl *cptr; |
65 | struct pvr2_sysfs *chptr; | 66 | struct pvr2_sysfs *chptr; |
66 | struct pvr2_sysfs_ctl_item *item_next; | 67 | struct pvr2_sysfs_ctl_item *item_next; |
67 | struct attribute *attr_gen[6]; | 68 | struct attribute *attr_gen[7]; |
68 | struct attribute_group grp; | 69 | struct attribute_group grp; |
69 | char name[80]; | 70 | char name[80]; |
70 | }; | 71 | }; |
@@ -92,6 +93,33 @@ static ssize_t show_name(int id,struct class_device *class_dev,char *buf) | |||
92 | return scnprintf(buf,PAGE_SIZE,"%s\n",name); | 93 | return scnprintf(buf,PAGE_SIZE,"%s\n",name); |
93 | } | 94 | } |
94 | 95 | ||
96 | static ssize_t show_type(int id,struct class_device *class_dev,char *buf) | ||
97 | { | ||
98 | struct pvr2_ctrl *cptr; | ||
99 | struct pvr2_sysfs *sfp; | ||
100 | const char *name; | ||
101 | enum pvr2_ctl_type tp; | ||
102 | |||
103 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
104 | if (!sfp) return -EINVAL; | ||
105 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
106 | if (!cptr) return -EINVAL; | ||
107 | |||
108 | tp = pvr2_ctrl_get_type(cptr); | ||
109 | switch (tp) { | ||
110 | case pvr2_ctl_int: name = "integer"; break; | ||
111 | case pvr2_ctl_enum: name = "enum"; break; | ||
112 | case pvr2_ctl_bitmask: name = "bitmask"; break; | ||
113 | case pvr2_ctl_bool: name = "boolean"; break; | ||
114 | default: name = "?"; break; | ||
115 | } | ||
116 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name); | ||
117 | |||
118 | if (!name) return -EINVAL; | ||
119 | |||
120 | return scnprintf(buf,PAGE_SIZE,"%s\n",name); | ||
121 | } | ||
122 | |||
95 | static ssize_t show_min(int id,struct class_device *class_dev,char *buf) | 123 | static ssize_t show_min(int id,struct class_device *class_dev,char *buf) |
96 | { | 124 | { |
97 | struct pvr2_ctrl *cptr; | 125 | struct pvr2_ctrl *cptr; |
@@ -289,6 +317,7 @@ static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf | |||
289 | 317 | ||
290 | #define CREATE_BATCH(ctl_id) \ | 318 | #define CREATE_BATCH(ctl_id) \ |
291 | CREATE_SHOW_INSTANCE(show_name,ctl_id) \ | 319 | CREATE_SHOW_INSTANCE(show_name,ctl_id) \ |
320 | CREATE_SHOW_INSTANCE(show_type,ctl_id) \ | ||
292 | CREATE_SHOW_INSTANCE(show_min,ctl_id) \ | 321 | CREATE_SHOW_INSTANCE(show_min,ctl_id) \ |
293 | CREATE_SHOW_INSTANCE(show_max,ctl_id) \ | 322 | CREATE_SHOW_INSTANCE(show_max,ctl_id) \ |
294 | CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \ | 323 | CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \ |
@@ -361,6 +390,7 @@ CREATE_BATCH(59) | |||
361 | 390 | ||
362 | struct pvr2_sysfs_func_set { | 391 | struct pvr2_sysfs_func_set { |
363 | ssize_t (*show_name)(struct class_device *,char *); | 392 | ssize_t (*show_name)(struct class_device *,char *); |
393 | ssize_t (*show_type)(struct class_device *,char *); | ||
364 | ssize_t (*show_min)(struct class_device *,char *); | 394 | ssize_t (*show_min)(struct class_device *,char *); |
365 | ssize_t (*show_max)(struct class_device *,char *); | 395 | ssize_t (*show_max)(struct class_device *,char *); |
366 | ssize_t (*show_enum)(struct class_device *,char *); | 396 | ssize_t (*show_enum)(struct class_device *,char *); |
@@ -376,6 +406,7 @@ struct pvr2_sysfs_func_set { | |||
376 | #define INIT_BATCH(ctl_id) \ | 406 | #define INIT_BATCH(ctl_id) \ |
377 | [ctl_id] = { \ | 407 | [ctl_id] = { \ |
378 | .show_name = show_name_##ctl_id, \ | 408 | .show_name = show_name_##ctl_id, \ |
409 | .show_type = show_type_##ctl_id, \ | ||
379 | .show_min = show_min_##ctl_id, \ | 410 | .show_min = show_min_##ctl_id, \ |
380 | .show_max = show_max_##ctl_id, \ | 411 | .show_max = show_max_##ctl_id, \ |
381 | .show_enum = show_enum_##ctl_id, \ | 412 | .show_enum = show_enum_##ctl_id, \ |
@@ -486,6 +517,11 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
486 | cip->attr_name.attr.mode = S_IRUGO; | 517 | cip->attr_name.attr.mode = S_IRUGO; |
487 | cip->attr_name.show = fp->show_name; | 518 | cip->attr_name.show = fp->show_name; |
488 | 519 | ||
520 | cip->attr_type.attr.owner = THIS_MODULE; | ||
521 | cip->attr_type.attr.name = "type"; | ||
522 | cip->attr_type.attr.mode = S_IRUGO; | ||
523 | cip->attr_type.show = fp->show_type; | ||
524 | |||
489 | cip->attr_min.attr.owner = THIS_MODULE; | 525 | cip->attr_min.attr.owner = THIS_MODULE; |
490 | cip->attr_min.attr.name = "min_val"; | 526 | cip->attr_min.attr.name = "min_val"; |
491 | cip->attr_min.attr.mode = S_IRUGO; | 527 | cip->attr_min.attr.mode = S_IRUGO; |
@@ -521,6 +557,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
521 | 557 | ||
522 | acnt = 0; | 558 | acnt = 0; |
523 | cip->attr_gen[acnt++] = &cip->attr_name.attr; | 559 | cip->attr_gen[acnt++] = &cip->attr_name.attr; |
560 | cip->attr_gen[acnt++] = &cip->attr_type.attr; | ||
524 | cip->attr_gen[acnt++] = &cip->attr_val.attr; | 561 | cip->attr_gen[acnt++] = &cip->attr_val.attr; |
525 | cip->attr_val.show = fp->show_val_norm; | 562 | cip->attr_val.show = fp->show_val_norm; |
526 | cip->attr_val.store = fp->store_val_norm; | 563 | cip->attr_val.store = fp->store_val_norm; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index da5d8fd9b09b..72f28a8e1fe3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -534,6 +534,12 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
534 | vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1; | 534 | vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1; |
535 | vc->step = 1; | 535 | vc->step = 1; |
536 | break; | 536 | break; |
537 | case pvr2_ctl_bool: | ||
538 | vc->type = V4L2_CTRL_TYPE_INTEGER; | ||
539 | vc->minimum = 0; | ||
540 | vc->maximum = 1; | ||
541 | vc->step = 1; | ||
542 | break; | ||
537 | case pvr2_ctl_int: | 543 | case pvr2_ctl_int: |
538 | vc->type = V4L2_CTRL_TYPE_INTEGER; | 544 | vc->type = V4L2_CTRL_TYPE_INTEGER; |
539 | vc->minimum = pvr2_ctrl_get_min(cptr); | 545 | vc->minimum = pvr2_ctrl_get_min(cptr); |