pvrusb2-ctrl.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  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. */
  16. #include "pvrusb2-ctrl.h"
  17. #include "pvrusb2-hdw-internal.h"
  18. #include <linux/errno.h>
  19. #include <linux/string.h>
  20. #include <linux/mutex.h>
  21. static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val)
  22. {
  23. if (cptr->info->check_value) {
  24. if (!cptr->info->check_value(cptr,val)) return -ERANGE;
  25. } else if (cptr->info->type == pvr2_ctl_enum) {
  26. if (val < 0) return -ERANGE;
  27. if (val >= cptr->info->def.type_enum.count) return -ERANGE;
  28. } else {
  29. int lim;
  30. lim = cptr->info->def.type_int.min_value;
  31. if (cptr->info->get_min_value) {
  32. cptr->info->get_min_value(cptr,&lim);
  33. }
  34. if (val < lim) return -ERANGE;
  35. lim = cptr->info->def.type_int.max_value;
  36. if (cptr->info->get_max_value) {
  37. cptr->info->get_max_value(cptr,&lim);
  38. }
  39. if (val > lim) return -ERANGE;
  40. }
  41. return 0;
  42. }
  43. /* Set the given control. */
  44. int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val)
  45. {
  46. return pvr2_ctrl_set_mask_value(cptr,~0,val);
  47. }
  48. /* Set/clear specific bits of the given control. */
  49. int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
  50. {
  51. int ret = 0;
  52. if (!cptr) return -EINVAL;
  53. LOCK_TAKE(cptr->hdw->big_lock); do {
  54. if (cptr->info->set_value) {
  55. if (cptr->info->type == pvr2_ctl_bitmask) {
  56. mask &= cptr->info->def.type_bitmask.valid_bits;
  57. } else if ((cptr->info->type == pvr2_ctl_int)||
  58. (cptr->info->type == pvr2_ctl_enum)) {
  59. ret = pvr2_ctrl_range_check(cptr,val);
  60. if (ret < 0) break;
  61. } else if (cptr->info->type != pvr2_ctl_bool) {
  62. break;
  63. }
  64. ret = cptr->info->set_value(cptr,mask,val);
  65. } else {
  66. ret = -EPERM;
  67. }
  68. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  69. return ret;
  70. }
  71. /* Get the current value of the given control. */
  72. int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr)
  73. {
  74. int ret = 0;
  75. if (!cptr) return -EINVAL;
  76. LOCK_TAKE(cptr->hdw->big_lock); do {
  77. ret = cptr->info->get_value(cptr,valptr);
  78. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  79. return ret;
  80. }
  81. /* Retrieve control's type */
  82. enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
  83. {
  84. if (!cptr) return pvr2_ctl_int;
  85. return cptr->info->type;
  86. }
  87. /* Retrieve control's maximum value (int type) */
  88. int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr)
  89. {
  90. int ret = 0;
  91. if (!cptr) return 0;
  92. LOCK_TAKE(cptr->hdw->big_lock); do {
  93. if (cptr->info->get_max_value) {
  94. cptr->info->get_max_value(cptr,&ret);
  95. } else if (cptr->info->type == pvr2_ctl_int) {
  96. ret = cptr->info->def.type_int.max_value;
  97. }
  98. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  99. return ret;
  100. }
  101. /* Retrieve control's minimum value (int type) */
  102. int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
  103. {
  104. int ret = 0;
  105. if (!cptr) return 0;
  106. LOCK_TAKE(cptr->hdw->big_lock); do {
  107. if (cptr->info->get_min_value) {
  108. cptr->info->get_min_value(cptr,&ret);
  109. } else if (cptr->info->type == pvr2_ctl_int) {
  110. ret = cptr->info->def.type_int.min_value;
  111. }
  112. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  113. return ret;
  114. }
  115. /* Retrieve control's default value (any type) */
  116. int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr)
  117. {
  118. int ret = 0;
  119. if (!cptr) return -EINVAL;
  120. LOCK_TAKE(cptr->hdw->big_lock); do {
  121. if (cptr->info->get_def_value) {
  122. ret = cptr->info->get_def_value(cptr, valptr);
  123. } else {
  124. *valptr = cptr->info->default_value;
  125. }
  126. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  127. return ret;
  128. }
  129. /* Retrieve control's enumeration count (enum only) */
  130. int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr)
  131. {
  132. int ret = 0;
  133. if (!cptr) return 0;
  134. LOCK_TAKE(cptr->hdw->big_lock); do {
  135. if (cptr->info->type == pvr2_ctl_enum) {
  136. ret = cptr->info->def.type_enum.count;
  137. }
  138. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  139. return ret;
  140. }
  141. /* Retrieve control's valid mask bits (bit mask only) */
  142. int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr)
  143. {
  144. int ret = 0;
  145. if (!cptr) return 0;
  146. LOCK_TAKE(cptr->hdw->big_lock); do {
  147. if (cptr->info->type == pvr2_ctl_bitmask) {
  148. ret = cptr->info->def.type_bitmask.valid_bits;
  149. }
  150. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  151. return ret;
  152. }
  153. /* Retrieve the control's name */
  154. const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
  155. {
  156. if (!cptr) return NULL;
  157. return cptr->info->name;
  158. }
  159. /* Retrieve the control's desc */
  160. const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
  161. {
  162. if (!cptr) return NULL;
  163. return cptr->info->desc;
  164. }
  165. /* Retrieve a control enumeration or bit mask value */
  166. int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
  167. char *bptr,unsigned int bmax,
  168. unsigned int *blen)
  169. {
  170. int ret = -EINVAL;
  171. if (!cptr) return 0;
  172. *blen = 0;
  173. LOCK_TAKE(cptr->hdw->big_lock); do {
  174. if (cptr->info->type == pvr2_ctl_enum) {
  175. const char * const *names;
  176. names = cptr->info->def.type_enum.value_names;
  177. if (pvr2_ctrl_range_check(cptr,val) == 0) {
  178. if (names[val]) {
  179. *blen = scnprintf(
  180. bptr,bmax,"%s",
  181. names[val]);
  182. } else {
  183. *blen = 0;
  184. }
  185. ret = 0;
  186. }
  187. } else if (cptr->info->type == pvr2_ctl_bitmask) {
  188. const char **names;
  189. unsigned int idx;
  190. int msk;
  191. names = cptr->info->def.type_bitmask.bit_names;
  192. val &= cptr->info->def.type_bitmask.valid_bits;
  193. for (idx = 0, msk = 1; val; idx++, msk <<= 1) {
  194. if (val & msk) {
  195. *blen = scnprintf(bptr,bmax,"%s",
  196. names[idx]);
  197. ret = 0;
  198. break;
  199. }
  200. }
  201. }
  202. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  203. return ret;
  204. }
  205. /* Return V4L ID for this control or zero if none */
  206. int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr)
  207. {
  208. if (!cptr) return 0;
  209. return cptr->info->v4l_id;
  210. }
  211. unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr)
  212. {
  213. unsigned int flags = 0;
  214. if (cptr->info->get_v4lflags) {
  215. flags = cptr->info->get_v4lflags(cptr);
  216. }
  217. if (cptr->info->set_value) {
  218. flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
  219. } else {
  220. flags |= V4L2_CTRL_FLAG_READ_ONLY;
  221. }
  222. return flags;
  223. }
  224. /* Return true if control is writable */
  225. int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr)
  226. {
  227. if (!cptr) return 0;
  228. return cptr->info->set_value != NULL;
  229. }
  230. /* Return true if control has custom symbolic representation */
  231. int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr)
  232. {
  233. if (!cptr) return 0;
  234. if (!cptr->info->val_to_sym) return 0;
  235. if (!cptr->info->sym_to_val) return 0;
  236. return !0;
  237. }
  238. /* Convert a given mask/val to a custom symbolic value */
  239. int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr,
  240. int mask,int val,
  241. char *buf,unsigned int maxlen,
  242. unsigned int *len)
  243. {
  244. if (!cptr) return -EINVAL;
  245. if (!cptr->info->val_to_sym) return -EINVAL;
  246. return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len);
  247. }
  248. /* Convert a symbolic value to a mask/value pair */
  249. int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr,
  250. const char *buf,unsigned int len,
  251. int *maskptr,int *valptr)
  252. {
  253. if (!cptr) return -EINVAL;
  254. if (!cptr->info->sym_to_val) return -EINVAL;
  255. return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr);
  256. }
  257. static unsigned int gen_bitmask_string(int msk,int val,int msk_only,
  258. const char **names,
  259. char *ptr,unsigned int len)
  260. {
  261. unsigned int idx;
  262. long sm,um;
  263. int spcFl;
  264. unsigned int uc,cnt;
  265. const char *idStr;
  266. spcFl = 0;
  267. uc = 0;
  268. um = 0;
  269. for (idx = 0, sm = 1; msk; idx++, sm <<= 1) {
  270. if (sm & msk) {
  271. msk &= ~sm;
  272. idStr = names[idx];
  273. if (idStr) {
  274. cnt = scnprintf(ptr,len,"%s%s%s",
  275. (spcFl ? " " : ""),
  276. (msk_only ? "" :
  277. ((val & sm) ? "+" : "-")),
  278. idStr);
  279. ptr += cnt; len -= cnt; uc += cnt;
  280. spcFl = !0;
  281. } else {
  282. um |= sm;
  283. }
  284. }
  285. }
  286. if (um) {
  287. if (msk_only) {
  288. cnt = scnprintf(ptr,len,"%s0x%lx",
  289. (spcFl ? " " : ""),
  290. um);
  291. ptr += cnt; len -= cnt; uc += cnt;
  292. spcFl = !0;
  293. } else if (um & val) {
  294. cnt = scnprintf(ptr,len,"%s+0x%lx",
  295. (spcFl ? " " : ""),
  296. um & val);
  297. ptr += cnt; len -= cnt; uc += cnt;
  298. spcFl = !0;
  299. } else if (um & ~val) {
  300. cnt = scnprintf(ptr,len,"%s+0x%lx",
  301. (spcFl ? " " : ""),
  302. um & ~val);
  303. ptr += cnt; len -= cnt; uc += cnt;
  304. spcFl = !0;
  305. }
  306. }
  307. return uc;
  308. }
  309. static const char *boolNames[] = {
  310. "false",
  311. "true",
  312. "no",
  313. "yes",
  314. };
  315. static int parse_token(const char *ptr,unsigned int len,
  316. int *valptr,
  317. const char * const *names, unsigned int namecnt)
  318. {
  319. char buf[33];
  320. unsigned int slen;
  321. unsigned int idx;
  322. int negfl;
  323. char *p2;
  324. *valptr = 0;
  325. if (!names) namecnt = 0;
  326. for (idx = 0; idx < namecnt; idx++) {
  327. if (!names[idx]) continue;
  328. slen = strlen(names[idx]);
  329. if (slen != len) continue;
  330. if (memcmp(names[idx],ptr,slen)) continue;
  331. *valptr = idx;
  332. return 0;
  333. }
  334. negfl = 0;
  335. if ((*ptr == '-') || (*ptr == '+')) {
  336. negfl = (*ptr == '-');
  337. ptr++; len--;
  338. }
  339. if (len >= sizeof(buf)) return -EINVAL;
  340. memcpy(buf,ptr,len);
  341. buf[len] = 0;
  342. *valptr = simple_strtol(buf,&p2,0);
  343. if (negfl) *valptr = -(*valptr);
  344. if (*p2) return -EINVAL;
  345. return 1;
  346. }
  347. static int parse_mtoken(const char *ptr,unsigned int len,
  348. int *valptr,
  349. const char **names,int valid_bits)
  350. {
  351. char buf[33];
  352. unsigned int slen;
  353. unsigned int idx;
  354. char *p2;
  355. int msk;
  356. *valptr = 0;
  357. for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) {
  358. if (!(msk & valid_bits)) continue;
  359. valid_bits &= ~msk;
  360. if (!names[idx]) continue;
  361. slen = strlen(names[idx]);
  362. if (slen != len) continue;
  363. if (memcmp(names[idx],ptr,slen)) continue;
  364. *valptr = msk;
  365. return 0;
  366. }
  367. if (len >= sizeof(buf)) return -EINVAL;
  368. memcpy(buf,ptr,len);
  369. buf[len] = 0;
  370. *valptr = simple_strtol(buf,&p2,0);
  371. if (*p2) return -EINVAL;
  372. return 0;
  373. }
  374. static int parse_tlist(const char *ptr,unsigned int len,
  375. int *maskptr,int *valptr,
  376. const char **names,int valid_bits)
  377. {
  378. unsigned int cnt;
  379. int mask,val,kv,mode,ret;
  380. mask = 0;
  381. val = 0;
  382. ret = 0;
  383. while (len) {
  384. cnt = 0;
  385. while ((cnt < len) &&
  386. ((ptr[cnt] <= 32) ||
  387. (ptr[cnt] >= 127))) cnt++;
  388. ptr += cnt;
  389. len -= cnt;
  390. mode = 0;
  391. if ((*ptr == '-') || (*ptr == '+')) {
  392. mode = (*ptr == '-') ? -1 : 1;
  393. ptr++;
  394. len--;
  395. }
  396. cnt = 0;
  397. while (cnt < len) {
  398. if (ptr[cnt] <= 32) break;
  399. if (ptr[cnt] >= 127) break;
  400. cnt++;
  401. }
  402. if (!cnt) break;
  403. if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) {
  404. ret = -EINVAL;
  405. break;
  406. }
  407. ptr += cnt;
  408. len -= cnt;
  409. switch (mode) {
  410. case 0:
  411. mask = valid_bits;
  412. val |= kv;
  413. break;
  414. case -1:
  415. mask |= kv;
  416. val &= ~kv;
  417. break;
  418. case 1:
  419. mask |= kv;
  420. val |= kv;
  421. break;
  422. default:
  423. break;
  424. }
  425. }
  426. *maskptr = mask;
  427. *valptr = val;
  428. return ret;
  429. }
  430. /* Convert a symbolic value to a mask/value pair */
  431. int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
  432. const char *ptr,unsigned int len,
  433. int *maskptr,int *valptr)
  434. {
  435. int ret = -EINVAL;
  436. unsigned int cnt;
  437. *maskptr = 0;
  438. *valptr = 0;
  439. cnt = 0;
  440. while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++;
  441. len -= cnt; ptr += cnt;
  442. cnt = 0;
  443. while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) ||
  444. (ptr[len-(cnt+1)] >= 127))) cnt++;
  445. len -= cnt;
  446. if (!len) return -EINVAL;
  447. LOCK_TAKE(cptr->hdw->big_lock); do {
  448. if (cptr->info->type == pvr2_ctl_int) {
  449. ret = parse_token(ptr,len,valptr,NULL,0);
  450. if (ret >= 0) {
  451. ret = pvr2_ctrl_range_check(cptr,*valptr);
  452. }
  453. *maskptr = ~0;
  454. } else if (cptr->info->type == pvr2_ctl_bool) {
  455. ret = parse_token(ptr,len,valptr,boolNames,
  456. ARRAY_SIZE(boolNames));
  457. if (ret == 1) {
  458. *valptr = *valptr ? !0 : 0;
  459. } else if (ret == 0) {
  460. *valptr = (*valptr & 1) ? !0 : 0;
  461. }
  462. *maskptr = 1;
  463. } else if (cptr->info->type == pvr2_ctl_enum) {
  464. ret = parse_token(
  465. ptr,len,valptr,
  466. cptr->info->def.type_enum.value_names,
  467. cptr->info->def.type_enum.count);
  468. if (ret >= 0) {
  469. ret = pvr2_ctrl_range_check(cptr,*valptr);
  470. }
  471. *maskptr = ~0;
  472. } else if (cptr->info->type == pvr2_ctl_bitmask) {
  473. ret = parse_tlist(
  474. ptr,len,maskptr,valptr,
  475. cptr->info->def.type_bitmask.bit_names,
  476. cptr->info->def.type_bitmask.valid_bits);
  477. }
  478. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  479. return ret;
  480. }
  481. /* Convert a given mask/val to a symbolic value */
  482. int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
  483. int mask,int val,
  484. char *buf,unsigned int maxlen,
  485. unsigned int *len)
  486. {
  487. int ret = -EINVAL;
  488. *len = 0;
  489. if (cptr->info->type == pvr2_ctl_int) {
  490. *len = scnprintf(buf,maxlen,"%d",val);
  491. ret = 0;
  492. } else if (cptr->info->type == pvr2_ctl_bool) {
  493. *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false");
  494. ret = 0;
  495. } else if (cptr->info->type == pvr2_ctl_enum) {
  496. const char * const *names;
  497. names = cptr->info->def.type_enum.value_names;
  498. if ((val >= 0) &&
  499. (val < cptr->info->def.type_enum.count)) {
  500. if (names[val]) {
  501. *len = scnprintf(
  502. buf,maxlen,"%s",
  503. names[val]);
  504. } else {
  505. *len = 0;
  506. }
  507. ret = 0;
  508. }
  509. } else if (cptr->info->type == pvr2_ctl_bitmask) {
  510. *len = gen_bitmask_string(
  511. val & mask & cptr->info->def.type_bitmask.valid_bits,
  512. ~0,!0,
  513. cptr->info->def.type_bitmask.bit_names,
  514. buf,maxlen);
  515. }
  516. return ret;
  517. }
  518. /* Convert a given mask/val to a symbolic value */
  519. int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr,
  520. int mask,int val,
  521. char *buf,unsigned int maxlen,
  522. unsigned int *len)
  523. {
  524. int ret;
  525. LOCK_TAKE(cptr->hdw->big_lock); do {
  526. ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val,
  527. buf,maxlen,len);
  528. } while(0); LOCK_GIVE(cptr->hdw->big_lock);
  529. return ret;
  530. }