Commit 33213963 authored by Mike Isely's avatar Mike Isely Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (4239): Handle boolean controls in pvrusb2

parent 077203a7
Loading
Loading
Loading
Loading
+28 −5
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
				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 unsigned int gen_bitmask_string(int msk,int val,int msk_only,
}


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 @@ static int parse_token(const char *ptr,unsigned int len,
	*valptr = simple_strtol(buf,&p2,0);
	if (negfl) *valptr = -(*valptr);
	if (*p2) return -EINVAL;
	return 0;
	return 1;
}


@@ -453,21 +463,31 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
	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 @@ int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
	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;
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ enum pvr2_ctl_type {
	pvr2_ctl_int = 0,
	pvr2_ctl_enum = 1,
	pvr2_ctl_bitmask = 2,
	pvr2_ctl_bool = 3,
};


+10 −6
Original line number Diff line number Diff line
@@ -436,6 +436,9 @@ static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
	.def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
	.def.type_enum.value_names = tab

#define DEFBOOL \
	.type = pvr2_ctl_bool

#define DEFMASK(msk,tab) \
	.type = pvr2_ctl_bitmask, \
	.def.type_bitmask.valid_bits = msk, \
@@ -548,7 +551,7 @@ static const struct pvr2_ctl_info control_defs[] = {
		.name = "mute",
		.default_value = 0,
		DEFREF(mute),
		DEFINT(0,1),
		DEFBOOL,
	},{
		.desc = "Video Source",
		.name = "input",
@@ -597,7 +600,7 @@ static const struct pvr2_ctl_info control_defs[] = {
		.name = "audio_crc",
		.default_value = 1,
		DEFREF(audiocrc),
		DEFINT(0,1),
		DEFBOOL,
	},{
		.v4l_id = V4L2_CID_PVR_AUDIOEMPHASIS,
		.desc = "Audio Emphasis",
@@ -611,7 +614,7 @@ static const struct pvr2_ctl_info control_defs[] = {
		.name = "vbr",
		.default_value = 0,
		DEFREF(vbr),
		DEFINT(0,1),
		DEFBOOL,
	},{
		.v4l_id = V4L2_CID_PVR_VIDEOBITRATE,
		.desc = "Average video bitrate",
@@ -632,7 +635,7 @@ static const struct pvr2_ctl_info control_defs[] = {
		.internal_id = PVR2_CID_INTERLACE,
		.default_value = 0,
		DEFREF(interlace),
		DEFINT(0,1),
		DEFBOOL,
	},{
		.desc = "Audio Layer",
		.name = "audio_layer",
@@ -671,7 +674,7 @@ static const struct pvr2_ctl_info control_defs[] = {
		.desc = "Streaming Enabled",
		.name = "streaming_enabled",
		.get_value = ctrl_streamingenabled_get,
		DEFINT(0,1),
		DEFBOOL,
	},{
		.desc = "USB Speed",
		.name = "usb_speed",
@@ -681,7 +684,7 @@ static const struct pvr2_ctl_info control_defs[] = {
		.desc = "Signal Present",
		.name = "signal_present",
		.get_value = ctrl_signal_get,
		DEFINT(0,1),
		DEFBOOL,
	},{
		.desc = "Video Standards Available Mask",
		.name = "video_standard_mask_available",
@@ -2007,6 +2010,7 @@ static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
	switch (tp) {
	case pvr2_ctl_int: return "integer";
	case pvr2_ctl_enum: return "enum";
	case pvr2_ctl_bool: return "boolean";
	case pvr2_ctl_bitmask: return "bitmask";
	}
	return "";
+38 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ struct pvr2_sysfs_debugifc {

struct pvr2_sysfs_ctl_item {
	struct class_device_attribute attr_name;
	struct class_device_attribute attr_type;
	struct class_device_attribute attr_min;
	struct class_device_attribute attr_max;
	struct class_device_attribute attr_enum;
@@ -64,7 +65,7 @@ struct pvr2_sysfs_ctl_item {
	struct pvr2_ctrl *cptr;
	struct pvr2_sysfs *chptr;
	struct pvr2_sysfs_ctl_item *item_next;
	struct attribute *attr_gen[6];
	struct attribute *attr_gen[7];
	struct attribute_group grp;
	char name[80];
};
@@ -92,6 +93,33 @@ static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
	return scnprintf(buf,PAGE_SIZE,"%s\n",name);
}

static ssize_t show_type(int id,struct class_device *class_dev,char *buf)
{
	struct pvr2_ctrl *cptr;
	struct pvr2_sysfs *sfp;
	const char *name;
	enum pvr2_ctl_type tp;

	sfp = (struct pvr2_sysfs *)class_dev->class_data;
	if (!sfp) return -EINVAL;
	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
	if (!cptr) return -EINVAL;

	tp = pvr2_ctrl_get_type(cptr);
	switch (tp) {
	case pvr2_ctl_int: name = "integer"; break;
	case pvr2_ctl_enum: name = "enum"; break;
	case pvr2_ctl_bitmask: name = "bitmask"; break;
	case pvr2_ctl_bool: name = "boolean"; break;
	default: name = "?"; break;
	}
	pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name);

	if (!name) return -EINVAL;

	return scnprintf(buf,PAGE_SIZE,"%s\n",name);
}

static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
{
	struct pvr2_ctrl *cptr;
@@ -289,6 +317,7 @@ static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf

#define CREATE_BATCH(ctl_id) \
CREATE_SHOW_INSTANCE(show_name,ctl_id) \
CREATE_SHOW_INSTANCE(show_type,ctl_id) \
CREATE_SHOW_INSTANCE(show_min,ctl_id) \
CREATE_SHOW_INSTANCE(show_max,ctl_id) \
CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
@@ -361,6 +390,7 @@ CREATE_BATCH(59)

struct pvr2_sysfs_func_set {
	ssize_t (*show_name)(struct class_device *,char *);
	ssize_t (*show_type)(struct class_device *,char *);
	ssize_t (*show_min)(struct class_device *,char *);
	ssize_t (*show_max)(struct class_device *,char *);
	ssize_t (*show_enum)(struct class_device *,char *);
@@ -376,6 +406,7 @@ struct pvr2_sysfs_func_set {
#define INIT_BATCH(ctl_id) \
[ctl_id] = { \
    .show_name = show_name_##ctl_id, \
    .show_type = show_type_##ctl_id, \
    .show_min = show_min_##ctl_id, \
    .show_max = show_max_##ctl_id, \
    .show_enum = show_enum_##ctl_id, \
@@ -486,6 +517,11 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
	cip->attr_name.attr.mode = S_IRUGO;
	cip->attr_name.show = fp->show_name;

	cip->attr_type.attr.owner = THIS_MODULE;
	cip->attr_type.attr.name = "type";
	cip->attr_type.attr.mode = S_IRUGO;
	cip->attr_type.show = fp->show_type;

	cip->attr_min.attr.owner = THIS_MODULE;
	cip->attr_min.attr.name = "min_val";
	cip->attr_min.attr.mode = S_IRUGO;
@@ -521,6 +557,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)

	acnt = 0;
	cip->attr_gen[acnt++] = &cip->attr_name.attr;
	cip->attr_gen[acnt++] = &cip->attr_type.attr;
	cip->attr_gen[acnt++] = &cip->attr_val.attr;
	cip->attr_val.show = fp->show_val_norm;
	cip->attr_val.store = fp->store_val_norm;
+6 −0
Original line number Diff line number Diff line
@@ -534,6 +534,12 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
			vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
			vc->step = 1;
			break;
		case pvr2_ctl_bool:
			vc->type = V4L2_CTRL_TYPE_INTEGER;
			vc->minimum = 0;
			vc->maximum = 1;
			vc->step = 1;
			break;
		case pvr2_ctl_int:
			vc->type = V4L2_CTRL_TYPE_INTEGER;
			vc->minimum = pvr2_ctrl_get_min(cptr);