 0c0d06cac6
			
		
	
	
	0c0d06cac6
	
	
	
		
			
			Rename all USB drivers with their own directory under drivers/media/video into drivers/media/usb and update the building system. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
		
			
				
	
	
		
			609 lines
		
	
	
	
		
			14 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			609 lines
		
	
	
	
		
			14 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *
 | |
|  *
 | |
|  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
 | |
|  *
 | |
|  *  This program is free software; you can redistribute it and/or modify
 | |
|  *  it under the terms of the GNU General Public License as published by
 | |
|  *  the Free Software Foundation; either version 2 of the License
 | |
|  *
 | |
|  *  This program is distributed in the hope that it will be useful,
 | |
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  *  GNU General Public License for more details.
 | |
|  *
 | |
|  *  You should have received a copy of the GNU General Public License
 | |
|  *  along with this program; if not, write to the Free Software
 | |
|  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #include "pvrusb2-ctrl.h"
 | |
| #include "pvrusb2-hdw-internal.h"
 | |
| #include <linux/errno.h>
 | |
| #include <linux/string.h>
 | |
| #include <linux/mutex.h>
 | |
| 
 | |
| 
 | |
| static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val)
 | |
| {
 | |
| 	if (cptr->info->check_value) {
 | |
| 		if (!cptr->info->check_value(cptr,val)) return -ERANGE;
 | |
| 	} else if (cptr->info->type == pvr2_ctl_enum) {
 | |
| 		if (val < 0) return -ERANGE;
 | |
| 		if (val >= cptr->info->def.type_enum.count) return -ERANGE;
 | |
| 	} else {
 | |
| 		int lim;
 | |
| 		lim = cptr->info->def.type_int.min_value;
 | |
| 		if (cptr->info->get_min_value) {
 | |
| 			cptr->info->get_min_value(cptr,&lim);
 | |
| 		}
 | |
| 		if (val < lim) return -ERANGE;
 | |
| 		lim = cptr->info->def.type_int.max_value;
 | |
| 		if (cptr->info->get_max_value) {
 | |
| 			cptr->info->get_max_value(cptr,&lim);
 | |
| 		}
 | |
| 		if (val > lim) return -ERANGE;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Set the given control. */
 | |
| int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val)
 | |
| {
 | |
| 	return pvr2_ctrl_set_mask_value(cptr,~0,val);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Set/clear specific bits of the given control. */
 | |
| int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 	if (!cptr) return -EINVAL;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		if (cptr->info->set_value) {
 | |
| 			if (cptr->info->type == pvr2_ctl_bitmask) {
 | |
| 				mask &= cptr->info->def.type_bitmask.valid_bits;
 | |
| 			} else if ((cptr->info->type == pvr2_ctl_int)||
 | |
| 				   (cptr->info->type == pvr2_ctl_enum)) {
 | |
| 				ret = pvr2_ctrl_range_check(cptr,val);
 | |
| 				if (ret < 0) break;
 | |
| 			} else if (cptr->info->type != pvr2_ctl_bool) {
 | |
| 				break;
 | |
| 			}
 | |
| 			ret = cptr->info->set_value(cptr,mask,val);
 | |
| 		} else {
 | |
| 			ret = -EPERM;
 | |
| 		}
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Get the current value of the given control. */
 | |
| int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 	if (!cptr) return -EINVAL;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		ret = cptr->info->get_value(cptr,valptr);
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve control's type */
 | |
| enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	if (!cptr) return pvr2_ctl_int;
 | |
| 	return cptr->info->type;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve control's maximum value (int type) */
 | |
| int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 	if (!cptr) return 0;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		if (cptr->info->get_max_value) {
 | |
| 			cptr->info->get_max_value(cptr,&ret);
 | |
| 		} else if (cptr->info->type == pvr2_ctl_int) {
 | |
| 			ret = cptr->info->def.type_int.max_value;
 | |
| 		}
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve control's minimum value (int type) */
 | |
| int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 	if (!cptr) return 0;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		if (cptr->info->get_min_value) {
 | |
| 			cptr->info->get_min_value(cptr,&ret);
 | |
| 		} else if (cptr->info->type == pvr2_ctl_int) {
 | |
| 			ret = cptr->info->def.type_int.min_value;
 | |
| 		}
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve control's default value (any type) */
 | |
| int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 	if (!cptr) return -EINVAL;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		if (cptr->info->get_def_value) {
 | |
| 			ret = cptr->info->get_def_value(cptr, valptr);
 | |
| 		} else {
 | |
| 			*valptr = cptr->info->default_value;
 | |
| 		}
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve control's enumeration count (enum only) */
 | |
| int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 	if (!cptr) return 0;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		if (cptr->info->type == pvr2_ctl_enum) {
 | |
| 			ret = cptr->info->def.type_enum.count;
 | |
| 		}
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve control's valid mask bits (bit mask only) */
 | |
| int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 	if (!cptr) return 0;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		if (cptr->info->type == pvr2_ctl_bitmask) {
 | |
| 			ret = cptr->info->def.type_bitmask.valid_bits;
 | |
| 		}
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve the control's name */
 | |
| const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	if (!cptr) return NULL;
 | |
| 	return cptr->info->name;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve the control's desc */
 | |
| const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	if (!cptr) return NULL;
 | |
| 	return cptr->info->desc;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Retrieve a control enumeration or bit mask value */
 | |
| int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
 | |
| 			  char *bptr,unsigned int bmax,
 | |
| 			  unsigned int *blen)
 | |
| {
 | |
| 	int ret = -EINVAL;
 | |
| 	if (!cptr) return 0;
 | |
| 	*blen = 0;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		if (cptr->info->type == pvr2_ctl_enum) {
 | |
| 			const char * const *names;
 | |
| 			names = cptr->info->def.type_enum.value_names;
 | |
| 			if (pvr2_ctrl_range_check(cptr,val) == 0) {
 | |
| 				if (names[val]) {
 | |
| 					*blen = scnprintf(
 | |
| 						bptr,bmax,"%s",
 | |
| 						names[val]);
 | |
| 				} else {
 | |
| 					*blen = 0;
 | |
| 				}
 | |
| 				ret = 0;
 | |
| 			}
 | |
| 		} else if (cptr->info->type == pvr2_ctl_bitmask) {
 | |
| 			const char **names;
 | |
| 			unsigned int idx;
 | |
| 			int msk;
 | |
| 			names = cptr->info->def.type_bitmask.bit_names;
 | |
| 			val &= cptr->info->def.type_bitmask.valid_bits;
 | |
| 			for (idx = 0, msk = 1; val; idx++, msk <<= 1) {
 | |
| 				if (val & msk) {
 | |
| 					*blen = scnprintf(bptr,bmax,"%s",
 | |
| 							  names[idx]);
 | |
| 					ret = 0;
 | |
| 					break;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Return V4L ID for this control or zero if none */
 | |
| int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	if (!cptr) return 0;
 | |
| 	return cptr->info->v4l_id;
 | |
| }
 | |
| 
 | |
| 
 | |
| unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	unsigned int flags = 0;
 | |
| 
 | |
| 	if (cptr->info->get_v4lflags) {
 | |
| 		flags = cptr->info->get_v4lflags(cptr);
 | |
| 	}
 | |
| 
 | |
| 	if (cptr->info->set_value) {
 | |
| 		flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
 | |
| 	} else {
 | |
| 		flags |= V4L2_CTRL_FLAG_READ_ONLY;
 | |
| 	}
 | |
| 
 | |
| 	return flags;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Return true if control is writable */
 | |
| int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	if (!cptr) return 0;
 | |
| 	return cptr->info->set_value != NULL;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Return true if control has custom symbolic representation */
 | |
| int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr)
 | |
| {
 | |
| 	if (!cptr) return 0;
 | |
| 	if (!cptr->info->val_to_sym) return 0;
 | |
| 	if (!cptr->info->sym_to_val) return 0;
 | |
| 	return !0;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Convert a given mask/val to a custom symbolic value */
 | |
| int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr,
 | |
| 				  int mask,int val,
 | |
| 				  char *buf,unsigned int maxlen,
 | |
| 				  unsigned int *len)
 | |
| {
 | |
| 	if (!cptr) return -EINVAL;
 | |
| 	if (!cptr->info->val_to_sym) return -EINVAL;
 | |
| 	return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Convert a symbolic value to a mask/value pair */
 | |
| int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr,
 | |
| 				  const char *buf,unsigned int len,
 | |
| 				  int *maskptr,int *valptr)
 | |
| {
 | |
| 	if (!cptr) return -EINVAL;
 | |
| 	if (!cptr->info->sym_to_val) return -EINVAL;
 | |
| 	return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr);
 | |
| }
 | |
| 
 | |
| 
 | |
| static unsigned int gen_bitmask_string(int msk,int val,int msk_only,
 | |
| 				       const char **names,
 | |
| 				       char *ptr,unsigned int len)
 | |
| {
 | |
| 	unsigned int idx;
 | |
| 	long sm,um;
 | |
| 	int spcFl;
 | |
| 	unsigned int uc,cnt;
 | |
| 	const char *idStr;
 | |
| 
 | |
| 	spcFl = 0;
 | |
| 	uc = 0;
 | |
| 	um = 0;
 | |
| 	for (idx = 0, sm = 1; msk; idx++, sm <<= 1) {
 | |
| 		if (sm & msk) {
 | |
| 			msk &= ~sm;
 | |
| 			idStr = names[idx];
 | |
| 			if (idStr) {
 | |
| 				cnt = scnprintf(ptr,len,"%s%s%s",
 | |
| 						(spcFl ? " " : ""),
 | |
| 						(msk_only ? "" :
 | |
| 						 ((val & sm) ? "+" : "-")),
 | |
| 						idStr);
 | |
| 				ptr += cnt; len -= cnt; uc += cnt;
 | |
| 				spcFl = !0;
 | |
| 			} else {
 | |
| 				um |= sm;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	if (um) {
 | |
| 		if (msk_only) {
 | |
| 			cnt = scnprintf(ptr,len,"%s0x%lx",
 | |
| 					(spcFl ? " " : ""),
 | |
| 					um);
 | |
| 			ptr += cnt; len -= cnt; uc += cnt;
 | |
| 			spcFl = !0;
 | |
| 		} else if (um & val) {
 | |
| 			cnt = scnprintf(ptr,len,"%s+0x%lx",
 | |
| 					(spcFl ? " " : ""),
 | |
| 					um & val);
 | |
| 			ptr += cnt; len -= cnt; uc += cnt;
 | |
| 			spcFl = !0;
 | |
| 		} else if (um & ~val) {
 | |
| 			cnt = scnprintf(ptr,len,"%s+0x%lx",
 | |
| 					(spcFl ? " " : ""),
 | |
| 					um & ~val);
 | |
| 			ptr += cnt; len -= cnt; uc += cnt;
 | |
| 			spcFl = !0;
 | |
| 		}
 | |
| 	}
 | |
| 	return uc;
 | |
| }
 | |
| 
 | |
| 
 | |
| static const char *boolNames[] = {
 | |
| 	"false",
 | |
| 	"true",
 | |
| 	"no",
 | |
| 	"yes",
 | |
| };
 | |
| 
 | |
| 
 | |
| static int parse_token(const char *ptr,unsigned int len,
 | |
| 		       int *valptr,
 | |
| 		       const char * const *names, unsigned int namecnt)
 | |
| {
 | |
| 	char buf[33];
 | |
| 	unsigned int slen;
 | |
| 	unsigned int idx;
 | |
| 	int negfl;
 | |
| 	char *p2;
 | |
| 	*valptr = 0;
 | |
| 	if (!names) namecnt = 0;
 | |
| 	for (idx = 0; idx < namecnt; idx++) {
 | |
| 		if (!names[idx]) continue;
 | |
| 		slen = strlen(names[idx]);
 | |
| 		if (slen != len) continue;
 | |
| 		if (memcmp(names[idx],ptr,slen)) continue;
 | |
| 		*valptr = idx;
 | |
| 		return 0;
 | |
| 	}
 | |
| 	negfl = 0;
 | |
| 	if ((*ptr == '-') || (*ptr == '+')) {
 | |
| 		negfl = (*ptr == '-');
 | |
| 		ptr++; len--;
 | |
| 	}
 | |
| 	if (len >= sizeof(buf)) return -EINVAL;
 | |
| 	memcpy(buf,ptr,len);
 | |
| 	buf[len] = 0;
 | |
| 	*valptr = simple_strtol(buf,&p2,0);
 | |
| 	if (negfl) *valptr = -(*valptr);
 | |
| 	if (*p2) return -EINVAL;
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| static int parse_mtoken(const char *ptr,unsigned int len,
 | |
| 			int *valptr,
 | |
| 			const char **names,int valid_bits)
 | |
| {
 | |
| 	char buf[33];
 | |
| 	unsigned int slen;
 | |
| 	unsigned int idx;
 | |
| 	char *p2;
 | |
| 	int msk;
 | |
| 	*valptr = 0;
 | |
| 	for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) {
 | |
| 		if (!(msk & valid_bits)) continue;
 | |
| 		valid_bits &= ~msk;
 | |
| 		if (!names[idx]) continue;
 | |
| 		slen = strlen(names[idx]);
 | |
| 		if (slen != len) continue;
 | |
| 		if (memcmp(names[idx],ptr,slen)) continue;
 | |
| 		*valptr = msk;
 | |
| 		return 0;
 | |
| 	}
 | |
| 	if (len >= sizeof(buf)) return -EINVAL;
 | |
| 	memcpy(buf,ptr,len);
 | |
| 	buf[len] = 0;
 | |
| 	*valptr = simple_strtol(buf,&p2,0);
 | |
| 	if (*p2) return -EINVAL;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| static int parse_tlist(const char *ptr,unsigned int len,
 | |
| 		       int *maskptr,int *valptr,
 | |
| 		       const char **names,int valid_bits)
 | |
| {
 | |
| 	unsigned int cnt;
 | |
| 	int mask,val,kv,mode,ret;
 | |
| 	mask = 0;
 | |
| 	val = 0;
 | |
| 	ret = 0;
 | |
| 	while (len) {
 | |
| 		cnt = 0;
 | |
| 		while ((cnt < len) &&
 | |
| 		       ((ptr[cnt] <= 32) ||
 | |
| 			(ptr[cnt] >= 127))) cnt++;
 | |
| 		ptr += cnt;
 | |
| 		len -= cnt;
 | |
| 		mode = 0;
 | |
| 		if ((*ptr == '-') || (*ptr == '+')) {
 | |
| 			mode = (*ptr == '-') ? -1 : 1;
 | |
| 			ptr++;
 | |
| 			len--;
 | |
| 		}
 | |
| 		cnt = 0;
 | |
| 		while (cnt < len) {
 | |
| 			if (ptr[cnt] <= 32) break;
 | |
| 			if (ptr[cnt] >= 127) break;
 | |
| 			cnt++;
 | |
| 		}
 | |
| 		if (!cnt) break;
 | |
| 		if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) {
 | |
| 			ret = -EINVAL;
 | |
| 			break;
 | |
| 		}
 | |
| 		ptr += cnt;
 | |
| 		len -= cnt;
 | |
| 		switch (mode) {
 | |
| 		case 0:
 | |
| 			mask = valid_bits;
 | |
| 			val |= kv;
 | |
| 			break;
 | |
| 		case -1:
 | |
| 			mask |= kv;
 | |
| 			val &= ~kv;
 | |
| 			break;
 | |
| 		case 1:
 | |
| 			mask |= kv;
 | |
| 			val |= kv;
 | |
| 			break;
 | |
| 		default:
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 	*maskptr = mask;
 | |
| 	*valptr = val;
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Convert a symbolic value to a mask/value pair */
 | |
| int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
 | |
| 			   const char *ptr,unsigned int len,
 | |
| 			   int *maskptr,int *valptr)
 | |
| {
 | |
| 	int ret = -EINVAL;
 | |
| 	unsigned int cnt;
 | |
| 
 | |
| 	*maskptr = 0;
 | |
| 	*valptr = 0;
 | |
| 
 | |
| 	cnt = 0;
 | |
| 	while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++;
 | |
| 	len -= cnt; ptr += cnt;
 | |
| 	cnt = 0;
 | |
| 	while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) ||
 | |
| 			       (ptr[len-(cnt+1)] >= 127))) cnt++;
 | |
| 	len -= cnt;
 | |
| 
 | |
| 	if (!len) return -EINVAL;
 | |
| 
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		if (cptr->info->type == pvr2_ctl_int) {
 | |
| 			ret = parse_token(ptr,len,valptr,NULL,0);
 | |
| 			if (ret >= 0) {
 | |
| 				ret = pvr2_ctrl_range_check(cptr,*valptr);
 | |
| 			}
 | |
| 			*maskptr = ~0;
 | |
| 		} else if (cptr->info->type == pvr2_ctl_bool) {
 | |
| 			ret = parse_token(ptr,len,valptr,boolNames,
 | |
| 					  ARRAY_SIZE(boolNames));
 | |
| 			if (ret == 1) {
 | |
| 				*valptr = *valptr ? !0 : 0;
 | |
| 			} else if (ret == 0) {
 | |
| 				*valptr = (*valptr & 1) ? !0 : 0;
 | |
| 			}
 | |
| 			*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) {
 | |
| 				ret = pvr2_ctrl_range_check(cptr,*valptr);
 | |
| 			}
 | |
| 			*maskptr = ~0;
 | |
| 		} else if (cptr->info->type == pvr2_ctl_bitmask) {
 | |
| 			ret = parse_tlist(
 | |
| 				ptr,len,maskptr,valptr,
 | |
| 				cptr->info->def.type_bitmask.bit_names,
 | |
| 				cptr->info->def.type_bitmask.valid_bits);
 | |
| 		}
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Convert a given mask/val to a symbolic value */
 | |
| int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
 | |
| 				    int mask,int val,
 | |
| 				    char *buf,unsigned int maxlen,
 | |
| 				    unsigned int *len)
 | |
| {
 | |
| 	int ret = -EINVAL;
 | |
| 
 | |
| 	*len = 0;
 | |
| 	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 * const *names;
 | |
| 		names = cptr->info->def.type_enum.value_names;
 | |
| 		if ((val >= 0) &&
 | |
| 		    (val < cptr->info->def.type_enum.count)) {
 | |
| 			if (names[val]) {
 | |
| 				*len = scnprintf(
 | |
| 					buf,maxlen,"%s",
 | |
| 					names[val]);
 | |
| 			} else {
 | |
| 				*len = 0;
 | |
| 			}
 | |
| 			ret = 0;
 | |
| 		}
 | |
| 	} else if (cptr->info->type == pvr2_ctl_bitmask) {
 | |
| 		*len = gen_bitmask_string(
 | |
| 			val & mask & cptr->info->def.type_bitmask.valid_bits,
 | |
| 			~0,!0,
 | |
| 			cptr->info->def.type_bitmask.bit_names,
 | |
| 			buf,maxlen);
 | |
| 	}
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Convert a given mask/val to a symbolic value */
 | |
| int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr,
 | |
| 			   int mask,int val,
 | |
| 			   char *buf,unsigned int maxlen,
 | |
| 			   unsigned int *len)
 | |
| {
 | |
| 	int ret;
 | |
| 	LOCK_TAKE(cptr->hdw->big_lock); do {
 | |
| 		ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val,
 | |
| 						      buf,maxlen,len);
 | |
| 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Stuff for Emacs to see, in order to encourage consistent editing style:
 | |
|   *** Local Variables: ***
 | |
|   *** mode: c ***
 | |
|   *** fill-column: 75 ***
 | |
|   *** tab-width: 8 ***
 | |
|   *** c-basic-offset: 8 ***
 | |
|   *** End: ***
 | |
|   */
 |