staticint pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val)
{ if (cptr->info->check_value) { if (!cptr->info->check_value(cptr,val)) return -ERANGE;
} elseif (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;
} elseif ((cptr->info->type == pvr2_ctl_int)||
(cptr->info->type == pvr2_ctl_enum)) {
ret = pvr2_ctrl_range_check(cptr,val); if (ret < 0) break;
} elseif (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);
} elseif (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);
} elseif (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 */ constchar *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
{ if (!cptr) return NULL; return cptr->info->name;
}
/* Retrieve the control's desc */ constchar *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,unsignedint bmax, unsignedint *blen)
{ int ret = -EINVAL; if (!cptr) return 0;
*blen = 0;
LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->type == pvr2_ctl_enum) { constchar * 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;
}
} elseif (cptr->info->type == pvr2_ctl_bitmask) { constchar **names; unsignedint 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;
}
/* 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,unsignedint maxlen, unsignedint *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, constchar *buf,unsignedint 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);
}
staticint parse_mtoken(constchar *ptr,unsignedint len, int *valptr, constchar **names,int valid_bits)
{ unsignedint slen; unsignedint idx; 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;
} return kstrtoint(ptr, 0, valptr);
}
staticint parse_tlist(constchar *ptr,unsignedint len, int *maskptr,int *valptr, constchar **names,int valid_bits)
{ unsignedint 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, constchar *ptr,unsignedint len, int *maskptr,int *valptr)
{ int ret = -EINVAL; unsignedint cnt;
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;
} elseif (cptr->info->type == pvr2_ctl_bool) {
ret = parse_token(ptr,len,valptr,boolNames,
ARRAY_SIZE(boolNames)); if (ret == 1) {
*valptr = *valptr ? !0 : 0;
} elseif (ret == 0) {
*valptr = (*valptr & 1) ? !0 : 0;
}
*maskptr = 1;
} elseif (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;
} elseif (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,unsignedint maxlen, unsignedint *len)
{ int ret = -EINVAL;
/* 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,unsignedint maxlen, unsignedint *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;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.