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>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index 3577d5b..d644afe 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -53,6 +53,8 @@
 				if (val >= cptr->info->def.type_enum.count) {
 					break;
 				}
+			} else if (cptr->info->type != pvr2_ctl_bool) {
+				break;
 			}
 			ret = cptr->info->set_value(cptr,mask,val);
 		} else {
@@ -308,6 +310,14 @@
 }
 
 
+static const char *boolNames[] = {
+	"false",
+	"true",
+	"no",
+	"yes",
+};
+
+
 static int parse_token(const char *ptr,unsigned int len,
 		       int *valptr,
 		       const char **names,unsigned int namecnt)
@@ -338,7 +348,7 @@
 	*valptr = simple_strtol(buf,&p2,0);
 	if (negfl) *valptr = -(*valptr);
 	if (*p2) return -EINVAL;
-	return 0;
+	return 1;
 }
 
 
@@ -453,21 +463,31 @@
 	LOCK_TAKE(cptr->hdw->big_lock); do {
 		if (cptr->info->type == pvr2_ctl_int) {
 			ret = parse_token(ptr,len,valptr,0,0);
-			if ((ret == 0) &&
+			if ((ret >= 0) &&
 			    ((*valptr < cptr->info->def.type_int.min_value) ||
 			     (*valptr > cptr->info->def.type_int.max_value))) {
-				ret = -EINVAL;
+				ret = -ERANGE;
 			}
 			if (maskptr) *maskptr = ~0;
+		} else if (cptr->info->type == pvr2_ctl_bool) {
+			ret = parse_token(
+				ptr,len,valptr,boolNames,
+				sizeof(boolNames)/sizeof(boolNames[0]));
+			if (ret == 1) {
+				*valptr = *valptr ? !0 : 0;
+			} else if (ret == 0) {
+				*valptr = (*valptr & 1) ? !0 : 0;
+			}
+			if (maskptr) *maskptr = 1;
 		} else if (cptr->info->type == pvr2_ctl_enum) {
 			ret = parse_token(
 				ptr,len,valptr,
 				cptr->info->def.type_enum.value_names,
 				cptr->info->def.type_enum.count);
-			if ((ret == 0) &&
+			if ((ret >= 0) &&
 			    ((*valptr < 0) ||
 			     (*valptr >= cptr->info->def.type_enum.count))) {
-				ret = -EINVAL;
+				ret = -ERANGE;
 			}
 			if (maskptr) *maskptr = ~0;
 		} else if (cptr->info->type == pvr2_ctl_bitmask) {
@@ -493,6 +513,9 @@
 	if (cptr->info->type == pvr2_ctl_int) {
 		*len = scnprintf(buf,maxlen,"%d",val);
 		ret = 0;
+	} else if (cptr->info->type == pvr2_ctl_bool) {
+		*len = scnprintf(buf,maxlen,"%s",val ? "true" : "false");
+		ret = 0;
 	} else if (cptr->info->type == pvr2_ctl_enum) {
 		const char **names;
 		names = cptr->info->def.type_enum.value_names;