diff options
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-ctrl.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-ctrl.c | 609 |
1 files changed, 609 insertions, 0 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c new file mode 100644 index 00000000000..7d5a7139a45 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c | |||
@@ -0,0 +1,609 @@ | |||
1 | /* | ||
2 | * | ||
3 | * | ||
4 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "pvrusb2-ctrl.h" | ||
22 | #include "pvrusb2-hdw-internal.h" | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/mutex.h> | ||
26 | |||
27 | |||
28 | static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val) | ||
29 | { | ||
30 | if (cptr->info->check_value) { | ||
31 | if (!cptr->info->check_value(cptr,val)) return -ERANGE; | ||
32 | } else if (cptr->info->type == pvr2_ctl_enum) { | ||
33 | if (val < 0) return -ERANGE; | ||
34 | if (val >= cptr->info->def.type_enum.count) return -ERANGE; | ||
35 | } else { | ||
36 | int lim; | ||
37 | lim = cptr->info->def.type_int.min_value; | ||
38 | if (cptr->info->get_min_value) { | ||
39 | cptr->info->get_min_value(cptr,&lim); | ||
40 | } | ||
41 | if (val < lim) return -ERANGE; | ||
42 | lim = cptr->info->def.type_int.max_value; | ||
43 | if (cptr->info->get_max_value) { | ||
44 | cptr->info->get_max_value(cptr,&lim); | ||
45 | } | ||
46 | if (val > lim) return -ERANGE; | ||
47 | } | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | |||
52 | /* Set the given control. */ | ||
53 | int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val) | ||
54 | { | ||
55 | return pvr2_ctrl_set_mask_value(cptr,~0,val); | ||
56 | } | ||
57 | |||
58 | |||
59 | /* Set/clear specific bits of the given control. */ | ||
60 | int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) | ||
61 | { | ||
62 | int ret = 0; | ||
63 | if (!cptr) return -EINVAL; | ||
64 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
65 | if (cptr->info->set_value) { | ||
66 | if (cptr->info->type == pvr2_ctl_bitmask) { | ||
67 | mask &= cptr->info->def.type_bitmask.valid_bits; | ||
68 | } else if ((cptr->info->type == pvr2_ctl_int)|| | ||
69 | (cptr->info->type == pvr2_ctl_enum)) { | ||
70 | ret = pvr2_ctrl_range_check(cptr,val); | ||
71 | if (ret < 0) break; | ||
72 | } else if (cptr->info->type != pvr2_ctl_bool) { | ||
73 | break; | ||
74 | } | ||
75 | ret = cptr->info->set_value(cptr,mask,val); | ||
76 | } else { | ||
77 | ret = -EPERM; | ||
78 | } | ||
79 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | |||
84 | /* Get the current value of the given control. */ | ||
85 | int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr) | ||
86 | { | ||
87 | int ret = 0; | ||
88 | if (!cptr) return -EINVAL; | ||
89 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
90 | ret = cptr->info->get_value(cptr,valptr); | ||
91 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | |||
96 | /* Retrieve control's type */ | ||
97 | enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr) | ||
98 | { | ||
99 | if (!cptr) return pvr2_ctl_int; | ||
100 | return cptr->info->type; | ||
101 | } | ||
102 | |||
103 | |||
104 | /* Retrieve control's maximum value (int type) */ | ||
105 | int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr) | ||
106 | { | ||
107 | int ret = 0; | ||
108 | if (!cptr) return 0; | ||
109 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
110 | if (cptr->info->get_max_value) { | ||
111 | cptr->info->get_max_value(cptr,&ret); | ||
112 | } else if (cptr->info->type == pvr2_ctl_int) { | ||
113 | ret = cptr->info->def.type_int.max_value; | ||
114 | } | ||
115 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | |||
120 | /* Retrieve control's minimum value (int type) */ | ||
121 | int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr) | ||
122 | { | ||
123 | int ret = 0; | ||
124 | if (!cptr) return 0; | ||
125 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
126 | if (cptr->info->get_min_value) { | ||
127 | cptr->info->get_min_value(cptr,&ret); | ||
128 | } else if (cptr->info->type == pvr2_ctl_int) { | ||
129 | ret = cptr->info->def.type_int.min_value; | ||
130 | } | ||
131 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | |||
136 | /* Retrieve control's default value (any type) */ | ||
137 | int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr) | ||
138 | { | ||
139 | int ret = 0; | ||
140 | if (!cptr) return -EINVAL; | ||
141 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
142 | if (cptr->info->get_def_value) { | ||
143 | ret = cptr->info->get_def_value(cptr, valptr); | ||
144 | } else { | ||
145 | *valptr = cptr->info->default_value; | ||
146 | } | ||
147 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | |||
152 | /* Retrieve control's enumeration count (enum only) */ | ||
153 | int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr) | ||
154 | { | ||
155 | int ret = 0; | ||
156 | if (!cptr) return 0; | ||
157 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
158 | if (cptr->info->type == pvr2_ctl_enum) { | ||
159 | ret = cptr->info->def.type_enum.count; | ||
160 | } | ||
161 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | |||
166 | /* Retrieve control's valid mask bits (bit mask only) */ | ||
167 | int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr) | ||
168 | { | ||
169 | int ret = 0; | ||
170 | if (!cptr) return 0; | ||
171 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
172 | if (cptr->info->type == pvr2_ctl_bitmask) { | ||
173 | ret = cptr->info->def.type_bitmask.valid_bits; | ||
174 | } | ||
175 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | |||
180 | /* Retrieve the control's name */ | ||
181 | const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr) | ||
182 | { | ||
183 | if (!cptr) return NULL; | ||
184 | return cptr->info->name; | ||
185 | } | ||
186 | |||
187 | |||
188 | /* Retrieve the control's desc */ | ||
189 | const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr) | ||
190 | { | ||
191 | if (!cptr) return NULL; | ||
192 | return cptr->info->desc; | ||
193 | } | ||
194 | |||
195 | |||
196 | /* Retrieve a control enumeration or bit mask value */ | ||
197 | int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, | ||
198 | char *bptr,unsigned int bmax, | ||
199 | unsigned int *blen) | ||
200 | { | ||
201 | int ret = -EINVAL; | ||
202 | if (!cptr) return 0; | ||
203 | *blen = 0; | ||
204 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
205 | if (cptr->info->type == pvr2_ctl_enum) { | ||
206 | const char * const *names; | ||
207 | names = cptr->info->def.type_enum.value_names; | ||
208 | if (pvr2_ctrl_range_check(cptr,val) == 0) { | ||
209 | if (names[val]) { | ||
210 | *blen = scnprintf( | ||
211 | bptr,bmax,"%s", | ||
212 | names[val]); | ||
213 | } else { | ||
214 | *blen = 0; | ||
215 | } | ||
216 | ret = 0; | ||
217 | } | ||
218 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | ||
219 | const char **names; | ||
220 | unsigned int idx; | ||
221 | int msk; | ||
222 | names = cptr->info->def.type_bitmask.bit_names; | ||
223 | val &= cptr->info->def.type_bitmask.valid_bits; | ||
224 | for (idx = 0, msk = 1; val; idx++, msk <<= 1) { | ||
225 | if (val & msk) { | ||
226 | *blen = scnprintf(bptr,bmax,"%s", | ||
227 | names[idx]); | ||
228 | ret = 0; | ||
229 | break; | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | |||
238 | /* Return V4L ID for this control or zero if none */ | ||
239 | int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr) | ||
240 | { | ||
241 | if (!cptr) return 0; | ||
242 | return cptr->info->v4l_id; | ||
243 | } | ||
244 | |||
245 | |||
246 | unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr) | ||
247 | { | ||
248 | unsigned int flags = 0; | ||
249 | |||
250 | if (cptr->info->get_v4lflags) { | ||
251 | flags = cptr->info->get_v4lflags(cptr); | ||
252 | } | ||
253 | |||
254 | if (cptr->info->set_value) { | ||
255 | flags &= ~V4L2_CTRL_FLAG_READ_ONLY; | ||
256 | } else { | ||
257 | flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||
258 | } | ||
259 | |||
260 | return flags; | ||
261 | } | ||
262 | |||
263 | |||
264 | /* Return true if control is writable */ | ||
265 | int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr) | ||
266 | { | ||
267 | if (!cptr) return 0; | ||
268 | return cptr->info->set_value != NULL; | ||
269 | } | ||
270 | |||
271 | |||
272 | /* Return true if control has custom symbolic representation */ | ||
273 | int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr) | ||
274 | { | ||
275 | if (!cptr) return 0; | ||
276 | if (!cptr->info->val_to_sym) return 0; | ||
277 | if (!cptr->info->sym_to_val) return 0; | ||
278 | return !0; | ||
279 | } | ||
280 | |||
281 | |||
282 | /* Convert a given mask/val to a custom symbolic value */ | ||
283 | int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr, | ||
284 | int mask,int val, | ||
285 | char *buf,unsigned int maxlen, | ||
286 | unsigned int *len) | ||
287 | { | ||
288 | if (!cptr) return -EINVAL; | ||
289 | if (!cptr->info->val_to_sym) return -EINVAL; | ||
290 | return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len); | ||
291 | } | ||
292 | |||
293 | |||
294 | /* Convert a symbolic value to a mask/value pair */ | ||
295 | int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr, | ||
296 | const char *buf,unsigned int len, | ||
297 | int *maskptr,int *valptr) | ||
298 | { | ||
299 | if (!cptr) return -EINVAL; | ||
300 | if (!cptr->info->sym_to_val) return -EINVAL; | ||
301 | return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr); | ||
302 | } | ||
303 | |||
304 | |||
305 | static unsigned int gen_bitmask_string(int msk,int val,int msk_only, | ||
306 | const char **names, | ||
307 | char *ptr,unsigned int len) | ||
308 | { | ||
309 | unsigned int idx; | ||
310 | long sm,um; | ||
311 | int spcFl; | ||
312 | unsigned int uc,cnt; | ||
313 | const char *idStr; | ||
314 | |||
315 | spcFl = 0; | ||
316 | uc = 0; | ||
317 | um = 0; | ||
318 | for (idx = 0, sm = 1; msk; idx++, sm <<= 1) { | ||
319 | if (sm & msk) { | ||
320 | msk &= ~sm; | ||
321 | idStr = names[idx]; | ||
322 | if (idStr) { | ||
323 | cnt = scnprintf(ptr,len,"%s%s%s", | ||
324 | (spcFl ? " " : ""), | ||
325 | (msk_only ? "" : | ||
326 | ((val & sm) ? "+" : "-")), | ||
327 | idStr); | ||
328 | ptr += cnt; len -= cnt; uc += cnt; | ||
329 | spcFl = !0; | ||
330 | } else { | ||
331 | um |= sm; | ||
332 | } | ||
333 | } | ||
334 | } | ||
335 | if (um) { | ||
336 | if (msk_only) { | ||
337 | cnt = scnprintf(ptr,len,"%s0x%lx", | ||
338 | (spcFl ? " " : ""), | ||
339 | um); | ||
340 | ptr += cnt; len -= cnt; uc += cnt; | ||
341 | spcFl = !0; | ||
342 | } else if (um & val) { | ||
343 | cnt = scnprintf(ptr,len,"%s+0x%lx", | ||
344 | (spcFl ? " " : ""), | ||
345 | um & val); | ||
346 | ptr += cnt; len -= cnt; uc += cnt; | ||
347 | spcFl = !0; | ||
348 | } else if (um & ~val) { | ||
349 | cnt = scnprintf(ptr,len,"%s+0x%lx", | ||
350 | (spcFl ? " " : ""), | ||
351 | um & ~val); | ||
352 | ptr += cnt; len -= cnt; uc += cnt; | ||
353 | spcFl = !0; | ||
354 | } | ||
355 | } | ||
356 | return uc; | ||
357 | } | ||
358 | |||
359 | |||
360 | static const char *boolNames[] = { | ||
361 | "false", | ||
362 | "true", | ||
363 | "no", | ||
364 | "yes", | ||
365 | }; | ||
366 | |||
367 | |||
368 | static int parse_token(const char *ptr,unsigned int len, | ||
369 | int *valptr, | ||
370 | const char * const *names, unsigned int namecnt) | ||
371 | { | ||
372 | char buf[33]; | ||
373 | unsigned int slen; | ||
374 | unsigned int idx; | ||
375 | int negfl; | ||
376 | char *p2; | ||
377 | *valptr = 0; | ||
378 | if (!names) namecnt = 0; | ||
379 | for (idx = 0; idx < namecnt; idx++) { | ||
380 | if (!names[idx]) continue; | ||
381 | slen = strlen(names[idx]); | ||
382 | if (slen != len) continue; | ||
383 | if (memcmp(names[idx],ptr,slen)) continue; | ||
384 | *valptr = idx; | ||
385 | return 0; | ||
386 | } | ||
387 | negfl = 0; | ||
388 | if ((*ptr == '-') || (*ptr == '+')) { | ||
389 | negfl = (*ptr == '-'); | ||
390 | ptr++; len--; | ||
391 | } | ||
392 | if (len >= sizeof(buf)) return -EINVAL; | ||
393 | memcpy(buf,ptr,len); | ||
394 | buf[len] = 0; | ||
395 | *valptr = simple_strtol(buf,&p2,0); | ||
396 | if (negfl) *valptr = -(*valptr); | ||
397 | if (*p2) return -EINVAL; | ||
398 | return 1; | ||
399 | } | ||
400 | |||
401 | |||
402 | static int parse_mtoken(const char *ptr,unsigned int len, | ||
403 | int *valptr, | ||
404 | const char **names,int valid_bits) | ||
405 | { | ||
406 | char buf[33]; | ||
407 | unsigned int slen; | ||
408 | unsigned int idx; | ||
409 | char *p2; | ||
410 | int msk; | ||
411 | *valptr = 0; | ||
412 | for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) { | ||
413 | if (!(msk & valid_bits)) continue; | ||
414 | valid_bits &= ~msk; | ||
415 | if (!names[idx]) continue; | ||
416 | slen = strlen(names[idx]); | ||
417 | if (slen != len) continue; | ||
418 | if (memcmp(names[idx],ptr,slen)) continue; | ||
419 | *valptr = msk; | ||
420 | return 0; | ||
421 | } | ||
422 | if (len >= sizeof(buf)) return -EINVAL; | ||
423 | memcpy(buf,ptr,len); | ||
424 | buf[len] = 0; | ||
425 | *valptr = simple_strtol(buf,&p2,0); | ||
426 | if (*p2) return -EINVAL; | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | |||
431 | static int parse_tlist(const char *ptr,unsigned int len, | ||
432 | int *maskptr,int *valptr, | ||
433 | const char **names,int valid_bits) | ||
434 | { | ||
435 | unsigned int cnt; | ||
436 | int mask,val,kv,mode,ret; | ||
437 | mask = 0; | ||
438 | val = 0; | ||
439 | ret = 0; | ||
440 | while (len) { | ||
441 | cnt = 0; | ||
442 | while ((cnt < len) && | ||
443 | ((ptr[cnt] <= 32) || | ||
444 | (ptr[cnt] >= 127))) cnt++; | ||
445 | ptr += cnt; | ||
446 | len -= cnt; | ||
447 | mode = 0; | ||
448 | if ((*ptr == '-') || (*ptr == '+')) { | ||
449 | mode = (*ptr == '-') ? -1 : 1; | ||
450 | ptr++; | ||
451 | len--; | ||
452 | } | ||
453 | cnt = 0; | ||
454 | while (cnt < len) { | ||
455 | if (ptr[cnt] <= 32) break; | ||
456 | if (ptr[cnt] >= 127) break; | ||
457 | cnt++; | ||
458 | } | ||
459 | if (!cnt) break; | ||
460 | if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) { | ||
461 | ret = -EINVAL; | ||
462 | break; | ||
463 | } | ||
464 | ptr += cnt; | ||
465 | len -= cnt; | ||
466 | switch (mode) { | ||
467 | case 0: | ||
468 | mask = valid_bits; | ||
469 | val |= kv; | ||
470 | break; | ||
471 | case -1: | ||
472 | mask |= kv; | ||
473 | val &= ~kv; | ||
474 | break; | ||
475 | case 1: | ||
476 | mask |= kv; | ||
477 | val |= kv; | ||
478 | break; | ||
479 | default: | ||
480 | break; | ||
481 | } | ||
482 | } | ||
483 | *maskptr = mask; | ||
484 | *valptr = val; | ||
485 | return ret; | ||
486 | } | ||
487 | |||
488 | |||
489 | /* Convert a symbolic value to a mask/value pair */ | ||
490 | int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, | ||
491 | const char *ptr,unsigned int len, | ||
492 | int *maskptr,int *valptr) | ||
493 | { | ||
494 | int ret = -EINVAL; | ||
495 | unsigned int cnt; | ||
496 | |||
497 | *maskptr = 0; | ||
498 | *valptr = 0; | ||
499 | |||
500 | cnt = 0; | ||
501 | while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++; | ||
502 | len -= cnt; ptr += cnt; | ||
503 | cnt = 0; | ||
504 | while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) || | ||
505 | (ptr[len-(cnt+1)] >= 127))) cnt++; | ||
506 | len -= cnt; | ||
507 | |||
508 | if (!len) return -EINVAL; | ||
509 | |||
510 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
511 | if (cptr->info->type == pvr2_ctl_int) { | ||
512 | ret = parse_token(ptr,len,valptr,NULL,0); | ||
513 | if (ret >= 0) { | ||
514 | ret = pvr2_ctrl_range_check(cptr,*valptr); | ||
515 | } | ||
516 | *maskptr = ~0; | ||
517 | } else if (cptr->info->type == pvr2_ctl_bool) { | ||
518 | ret = parse_token(ptr,len,valptr,boolNames, | ||
519 | ARRAY_SIZE(boolNames)); | ||
520 | if (ret == 1) { | ||
521 | *valptr = *valptr ? !0 : 0; | ||
522 | } else if (ret == 0) { | ||
523 | *valptr = (*valptr & 1) ? !0 : 0; | ||
524 | } | ||
525 | *maskptr = 1; | ||
526 | } else if (cptr->info->type == pvr2_ctl_enum) { | ||
527 | ret = parse_token( | ||
528 | ptr,len,valptr, | ||
529 | cptr->info->def.type_enum.value_names, | ||
530 | cptr->info->def.type_enum.count); | ||
531 | if (ret >= 0) { | ||
532 | ret = pvr2_ctrl_range_check(cptr,*valptr); | ||
533 | } | ||
534 | *maskptr = ~0; | ||
535 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | ||
536 | ret = parse_tlist( | ||
537 | ptr,len,maskptr,valptr, | ||
538 | cptr->info->def.type_bitmask.bit_names, | ||
539 | cptr->info->def.type_bitmask.valid_bits); | ||
540 | } | ||
541 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | |||
546 | /* Convert a given mask/val to a symbolic value */ | ||
547 | int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr, | ||
548 | int mask,int val, | ||
549 | char *buf,unsigned int maxlen, | ||
550 | unsigned int *len) | ||
551 | { | ||
552 | int ret = -EINVAL; | ||
553 | |||
554 | *len = 0; | ||
555 | if (cptr->info->type == pvr2_ctl_int) { | ||
556 | *len = scnprintf(buf,maxlen,"%d",val); | ||
557 | ret = 0; | ||
558 | } else if (cptr->info->type == pvr2_ctl_bool) { | ||
559 | *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); | ||
560 | ret = 0; | ||
561 | } else if (cptr->info->type == pvr2_ctl_enum) { | ||
562 | const char * const *names; | ||
563 | names = cptr->info->def.type_enum.value_names; | ||
564 | if ((val >= 0) && | ||
565 | (val < cptr->info->def.type_enum.count)) { | ||
566 | if (names[val]) { | ||
567 | *len = scnprintf( | ||
568 | buf,maxlen,"%s", | ||
569 | names[val]); | ||
570 | } else { | ||
571 | *len = 0; | ||
572 | } | ||
573 | ret = 0; | ||
574 | } | ||
575 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | ||
576 | *len = gen_bitmask_string( | ||
577 | val & mask & cptr->info->def.type_bitmask.valid_bits, | ||
578 | ~0,!0, | ||
579 | cptr->info->def.type_bitmask.bit_names, | ||
580 | buf,maxlen); | ||
581 | } | ||
582 | return ret; | ||
583 | } | ||
584 | |||
585 | |||
586 | /* Convert a given mask/val to a symbolic value */ | ||
587 | int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr, | ||
588 | int mask,int val, | ||
589 | char *buf,unsigned int maxlen, | ||
590 | unsigned int *len) | ||
591 | { | ||
592 | int ret; | ||
593 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
594 | ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val, | ||
595 | buf,maxlen,len); | ||
596 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
597 | return ret; | ||
598 | } | ||
599 | |||
600 | |||
601 | /* | ||
602 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
603 | *** Local Variables: *** | ||
604 | *** mode: c *** | ||
605 | *** fill-column: 75 *** | ||
606 | *** tab-width: 8 *** | ||
607 | *** c-basic-offset: 8 *** | ||
608 | *** End: *** | ||
609 | */ | ||