pwc-ctrl.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. /* Driver for Philips webcam
  2. Functions that send various control messages to the webcam, including
  3. video modes.
  4. (C) 1999-2003 Nemosoft Unv.
  5. (C) 2004-2006 Luc Saillard (luc@saillard.org)
  6. (C) 2011 Hans de Goede <hdegoede@redhat.com>
  7. NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
  8. driver and thus may have bugs that are not present in the original version.
  9. Please send bug reports and support requests to <luc@saillard.org>.
  10. NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
  11. driver and thus may have bugs that are not present in the original version.
  12. Please send bug reports and support requests to <luc@saillard.org>.
  13. The decompression routines have been implemented by reverse-engineering the
  14. Nemosoft binary pwcx module. Caveat emptor.
  15. This program is free software; you can redistribute it and/or modify
  16. it under the terms of the GNU General Public License as published by
  17. the Free Software Foundation; either version 2 of the License, or
  18. (at your option) any later version.
  19. This program is distributed in the hope that it will be useful,
  20. but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. GNU General Public License for more details.
  23. You should have received a copy of the GNU General Public License
  24. along with this program; if not, write to the Free Software
  25. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. */
  27. /*
  28. Changes
  29. 2001/08/03 Alvarado Added methods for changing white balance and
  30. red/green gains
  31. */
  32. /* Control functions for the cam; brightness, contrast, video mode, etc. */
  33. #ifdef __KERNEL__
  34. #include <asm/uaccess.h>
  35. #endif
  36. #include <asm/errno.h>
  37. #include "pwc.h"
  38. #include "pwc-kiara.h"
  39. #include "pwc-timon.h"
  40. #include "pwc-dec1.h"
  41. #include "pwc-dec23.h"
  42. /* Selectors for status controls used only in this file */
  43. #define GET_STATUS_B00 0x0B00
  44. #define SENSOR_TYPE_FORMATTER1 0x0C00
  45. #define GET_STATUS_3000 0x3000
  46. #define READ_RAW_Y_MEAN_FORMATTER 0x3100
  47. #define SET_POWER_SAVE_MODE_FORMATTER 0x3200
  48. #define MIRROR_IMAGE_FORMATTER 0x3300
  49. #define LED_FORMATTER 0x3400
  50. #define LOWLIGHT 0x3500
  51. #define GET_STATUS_3600 0x3600
  52. #define SENSOR_TYPE_FORMATTER2 0x3700
  53. #define GET_STATUS_3800 0x3800
  54. #define GET_STATUS_4000 0x4000
  55. #define GET_STATUS_4100 0x4100 /* Get */
  56. #define CTL_STATUS_4200 0x4200 /* [GS] 1 */
  57. /* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
  58. #define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100
  59. static const char *size2name[PSZ_MAX] =
  60. {
  61. "subQCIF",
  62. "QSIF",
  63. "QCIF",
  64. "SIF",
  65. "CIF",
  66. "VGA",
  67. };
  68. /********/
  69. /* Entries for the Nala (645/646) camera; the Nala doesn't have compression
  70. preferences, so you either get compressed or non-compressed streams.
  71. An alternate value of 0 means this mode is not available at all.
  72. */
  73. #define PWC_FPS_MAX_NALA 8
  74. struct Nala_table_entry {
  75. char alternate; /* USB alternate setting */
  76. int compressed; /* Compressed yes/no */
  77. unsigned char mode[3]; /* precomputed mode table */
  78. };
  79. static unsigned int Nala_fps_vector[PWC_FPS_MAX_NALA] = { 4, 5, 7, 10, 12, 15, 20, 24 };
  80. static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
  81. {
  82. #include "pwc-nala.h"
  83. };
  84. static void pwc_set_image_buffer_size(struct pwc_device *pdev);
  85. /****************************************************************************/
  86. static int _send_control_msg(struct pwc_device *pdev,
  87. u8 request, u16 value, int index, void *buf, int buflen)
  88. {
  89. int rc;
  90. void *kbuf = NULL;
  91. if (buflen) {
  92. kbuf = kmemdup(buf, buflen, GFP_KERNEL); /* not allowed on stack */
  93. if (kbuf == NULL)
  94. return -ENOMEM;
  95. }
  96. rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
  97. request,
  98. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  99. value,
  100. index,
  101. kbuf, buflen, USB_CTRL_SET_TIMEOUT);
  102. kfree(kbuf);
  103. return rc;
  104. }
  105. static int recv_control_msg(struct pwc_device *pdev,
  106. u8 request, u16 value, void *buf, int buflen)
  107. {
  108. int rc;
  109. void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
  110. if (kbuf == NULL)
  111. return -ENOMEM;
  112. rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
  113. request,
  114. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  115. value,
  116. pdev->vcinterface,
  117. kbuf, buflen, USB_CTRL_GET_TIMEOUT);
  118. memcpy(buf, kbuf, buflen);
  119. kfree(kbuf);
  120. if (rc < 0)
  121. PWC_ERROR("recv_control_msg error %d req %02x val %04x\n",
  122. rc, request, value);
  123. return rc;
  124. }
  125. static inline int send_video_command(struct pwc_device *pdev,
  126. int index, void *buf, int buflen)
  127. {
  128. return _send_control_msg(pdev,
  129. SET_EP_STREAM_CTL,
  130. VIDEO_OUTPUT_CONTROL_FORMATTER,
  131. index,
  132. buf, buflen);
  133. }
  134. int send_control_msg(struct pwc_device *pdev,
  135. u8 request, u16 value, void *buf, int buflen)
  136. {
  137. return _send_control_msg(pdev,
  138. request, value, pdev->vcinterface, buf, buflen);
  139. }
  140. static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
  141. {
  142. unsigned char buf[3];
  143. int ret, fps;
  144. struct Nala_table_entry *pEntry;
  145. int frames2frames[31] =
  146. { /* closest match of framerate */
  147. 0, 0, 0, 0, 4, /* 0-4 */
  148. 5, 5, 7, 7, 10, /* 5-9 */
  149. 10, 10, 12, 12, 15, /* 10-14 */
  150. 15, 15, 15, 20, 20, /* 15-19 */
  151. 20, 20, 20, 24, 24, /* 20-24 */
  152. 24, 24, 24, 24, 24, /* 25-29 */
  153. 24 /* 30 */
  154. };
  155. int frames2table[31] =
  156. { 0, 0, 0, 0, 0, /* 0-4 */
  157. 1, 1, 1, 2, 2, /* 5-9 */
  158. 3, 3, 4, 4, 4, /* 10-14 */
  159. 5, 5, 5, 5, 5, /* 15-19 */
  160. 6, 6, 6, 6, 7, /* 20-24 */
  161. 7, 7, 7, 7, 7, /* 25-29 */
  162. 7 /* 30 */
  163. };
  164. if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
  165. return -EINVAL;
  166. frames = frames2frames[frames];
  167. fps = frames2table[frames];
  168. pEntry = &Nala_table[size][fps];
  169. if (pEntry->alternate == 0)
  170. return -EINVAL;
  171. memcpy(buf, pEntry->mode, 3);
  172. ret = send_video_command(pdev, pdev->vendpoint, buf, 3);
  173. if (ret < 0) {
  174. PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
  175. return ret;
  176. }
  177. if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
  178. ret = pwc_dec1_init(pdev, pdev->type, pdev->release, buf);
  179. if (ret < 0)
  180. return ret;
  181. }
  182. pdev->cmd_len = 3;
  183. memcpy(pdev->cmd_buf, buf, 3);
  184. /* Set various parameters */
  185. pdev->vframes = frames;
  186. pdev->vsize = size;
  187. pdev->valternate = pEntry->alternate;
  188. pdev->image = pwc_image_sizes[size];
  189. pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2;
  190. if (pEntry->compressed) {
  191. if (pdev->release < 5) { /* 4 fold compression */
  192. pdev->vbandlength = 528;
  193. pdev->frame_size /= 4;
  194. }
  195. else {
  196. pdev->vbandlength = 704;
  197. pdev->frame_size /= 3;
  198. }
  199. }
  200. else
  201. pdev->vbandlength = 0;
  202. return 0;
  203. }
  204. static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
  205. {
  206. unsigned char buf[13];
  207. const struct Timon_table_entry *pChoose;
  208. int ret, fps;
  209. if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
  210. return -EINVAL;
  211. if (size == PSZ_VGA && frames > 15)
  212. return -EINVAL;
  213. fps = (frames / 5) - 1;
  214. /* Find a supported framerate with progressively higher compression ratios
  215. if the preferred ratio is not available.
  216. */
  217. pChoose = NULL;
  218. while (compression <= 3) {
  219. pChoose = &Timon_table[size][fps][compression];
  220. if (pChoose->alternate != 0)
  221. break;
  222. compression++;
  223. }
  224. if (pChoose == NULL || pChoose->alternate == 0)
  225. return -ENOENT; /* Not supported. */
  226. memcpy(buf, pChoose->mode, 13);
  227. if (snapshot)
  228. buf[0] |= 0x80;
  229. ret = send_video_command(pdev, pdev->vendpoint, buf, 13);
  230. if (ret < 0)
  231. return ret;
  232. if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
  233. ret = pwc_dec23_init(pdev, pdev->type, buf);
  234. if (ret < 0)
  235. return ret;
  236. }
  237. pdev->cmd_len = 13;
  238. memcpy(pdev->cmd_buf, buf, 13);
  239. /* Set various parameters */
  240. pdev->vframes = frames;
  241. pdev->vsize = size;
  242. pdev->vsnapshot = snapshot;
  243. pdev->valternate = pChoose->alternate;
  244. pdev->image = pwc_image_sizes[size];
  245. pdev->vbandlength = pChoose->bandlength;
  246. if (pChoose->bandlength > 0)
  247. pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4;
  248. else
  249. pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
  250. return 0;
  251. }
  252. static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
  253. {
  254. const struct Kiara_table_entry *pChoose = NULL;
  255. int fps, ret;
  256. unsigned char buf[12];
  257. struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}};
  258. if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
  259. return -EINVAL;
  260. if (size == PSZ_VGA && frames > 15)
  261. return -EINVAL;
  262. fps = (frames / 5) - 1;
  263. /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
  264. if (size == PSZ_VGA && frames == 5 && snapshot && pdev->pixfmt != V4L2_PIX_FMT_YUV420)
  265. {
  266. /* Only available in case the raw palette is selected or
  267. we have the decompressor available. This mode is
  268. only available in compressed form
  269. */
  270. PWC_DEBUG_SIZE("Choosing VGA/5 BAYER mode.\n");
  271. pChoose = &RawEntry;
  272. }
  273. else
  274. {
  275. /* Find a supported framerate with progressively higher compression ratios
  276. if the preferred ratio is not available.
  277. Skip this step when using RAW modes.
  278. */
  279. snapshot = 0;
  280. while (compression <= 3) {
  281. pChoose = &Kiara_table[size][fps][compression];
  282. if (pChoose->alternate != 0)
  283. break;
  284. compression++;
  285. }
  286. }
  287. if (pChoose == NULL || pChoose->alternate == 0)
  288. return -ENOENT; /* Not supported. */
  289. PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate);
  290. /* usb_control_msg won't take staticly allocated arrays as argument?? */
  291. memcpy(buf, pChoose->mode, 12);
  292. if (snapshot)
  293. buf[0] |= 0x80;
  294. /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
  295. ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12);
  296. if (ret < 0)
  297. return ret;
  298. if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
  299. ret = pwc_dec23_init(pdev, pdev->type, buf);
  300. if (ret < 0)
  301. return ret;
  302. }
  303. pdev->cmd_len = 12;
  304. memcpy(pdev->cmd_buf, buf, 12);
  305. /* All set and go */
  306. pdev->vframes = frames;
  307. pdev->vsize = size;
  308. pdev->vsnapshot = snapshot;
  309. pdev->valternate = pChoose->alternate;
  310. pdev->image = pwc_image_sizes[size];
  311. pdev->vbandlength = pChoose->bandlength;
  312. if (pdev->vbandlength > 0)
  313. pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
  314. else
  315. pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
  316. PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vsnapshot=%d, vbandlength=%d\n",
  317. pdev->frame_size,pdev->vframes,pdev->vsize,pdev->vsnapshot,pdev->vbandlength);
  318. return 0;
  319. }
  320. /**
  321. @pdev: device structure
  322. @width: viewport width
  323. @height: viewport height
  324. @frame: framerate, in fps
  325. @compression: preferred compression ratio
  326. @snapshot: snapshot mode or streaming
  327. */
  328. int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
  329. {
  330. int ret, size;
  331. PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt);
  332. size = pwc_decode_size(pdev, width, height);
  333. if (size < 0) {
  334. PWC_DEBUG_MODULE("Could not find suitable size.\n");
  335. return -ERANGE;
  336. }
  337. PWC_TRACE("decode_size = %d.\n", size);
  338. if (DEVICE_USE_CODEC1(pdev->type)) {
  339. ret = set_video_mode_Nala(pdev, size, frames);
  340. } else if (DEVICE_USE_CODEC3(pdev->type)) {
  341. ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot);
  342. } else {
  343. ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
  344. }
  345. if (ret < 0) {
  346. PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
  347. return ret;
  348. }
  349. pdev->view.x = width;
  350. pdev->view.y = height;
  351. pdev->vcompression = compression;
  352. pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
  353. pwc_set_image_buffer_size(pdev);
  354. PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
  355. return 0;
  356. }
  357. static unsigned int pwc_get_fps_Nala(struct pwc_device *pdev, unsigned int index, unsigned int size)
  358. {
  359. unsigned int i;
  360. for (i = 0; i < PWC_FPS_MAX_NALA; i++) {
  361. if (Nala_table[size][i].alternate) {
  362. if (index--==0) return Nala_fps_vector[i];
  363. }
  364. }
  365. return 0;
  366. }
  367. static unsigned int pwc_get_fps_Kiara(struct pwc_device *pdev, unsigned int index, unsigned int size)
  368. {
  369. unsigned int i;
  370. for (i = 0; i < PWC_FPS_MAX_KIARA; i++) {
  371. if (Kiara_table[size][i][3].alternate) {
  372. if (index--==0) return Kiara_fps_vector[i];
  373. }
  374. }
  375. return 0;
  376. }
  377. static unsigned int pwc_get_fps_Timon(struct pwc_device *pdev, unsigned int index, unsigned int size)
  378. {
  379. unsigned int i;
  380. for (i=0; i < PWC_FPS_MAX_TIMON; i++) {
  381. if (Timon_table[size][i][3].alternate) {
  382. if (index--==0) return Timon_fps_vector[i];
  383. }
  384. }
  385. return 0;
  386. }
  387. unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size)
  388. {
  389. unsigned int ret;
  390. if (DEVICE_USE_CODEC1(pdev->type)) {
  391. ret = pwc_get_fps_Nala(pdev, index, size);
  392. } else if (DEVICE_USE_CODEC3(pdev->type)) {
  393. ret = pwc_get_fps_Kiara(pdev, index, size);
  394. } else {
  395. ret = pwc_get_fps_Timon(pdev, index, size);
  396. }
  397. return ret;
  398. }
  399. static void pwc_set_image_buffer_size(struct pwc_device *pdev)
  400. {
  401. int factor = 0;
  402. /* for V4L2_PIX_FMT_YUV420 */
  403. switch (pdev->pixfmt) {
  404. case V4L2_PIX_FMT_YUV420:
  405. factor = 6;
  406. break;
  407. case V4L2_PIX_FMT_PWC1:
  408. case V4L2_PIX_FMT_PWC2:
  409. factor = 6; /* can be uncompressed YUV420P */
  410. break;
  411. }
  412. /* Set sizes in bytes */
  413. pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
  414. pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
  415. /* Align offset, or you'll get some very weird results in
  416. YUV420 mode... x must be multiple of 4 (to get the Y's in
  417. place), and y even (or you'll mixup U & V). This is less of a
  418. problem for YUV420P.
  419. */
  420. pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
  421. pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
  422. }
  423. int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
  424. {
  425. int ret;
  426. u8 buf;
  427. ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
  428. if (ret < 0)
  429. return ret;
  430. *data = buf;
  431. return 0;
  432. }
  433. int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
  434. {
  435. int ret;
  436. ret = send_control_msg(pdev, request, value, &data, sizeof(data));
  437. if (ret < 0)
  438. return ret;
  439. return 0;
  440. }
  441. int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
  442. {
  443. int ret;
  444. s8 buf;
  445. ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
  446. if (ret < 0)
  447. return ret;
  448. *data = buf;
  449. return 0;
  450. }
  451. int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
  452. {
  453. int ret;
  454. u8 buf[2];
  455. ret = recv_control_msg(pdev, request, value, buf, sizeof(buf));
  456. if (ret < 0)
  457. return ret;
  458. *data = (buf[1] << 8) | buf[0];
  459. return 0;
  460. }
  461. int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
  462. {
  463. int ret;
  464. u8 buf[2];
  465. buf[0] = data & 0xff;
  466. buf[1] = data >> 8;
  467. ret = send_control_msg(pdev, request, value, buf, sizeof(buf));
  468. if (ret < 0)
  469. return ret;
  470. return 0;
  471. }
  472. int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
  473. {
  474. int ret;
  475. ret = send_control_msg(pdev, SET_STATUS_CTL, value, NULL, 0);
  476. if (ret < 0)
  477. return ret;
  478. return 0;
  479. }
  480. /* POWER */
  481. void pwc_camera_power(struct pwc_device *pdev, int power)
  482. {
  483. char buf;
  484. int r;
  485. if (!pdev->power_save)
  486. return;
  487. if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
  488. return; /* Not supported by Nala or Timon < release 6 */
  489. if (power)
  490. buf = 0x00; /* active */
  491. else
  492. buf = 0xFF; /* power save */
  493. r = send_control_msg(pdev,
  494. SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
  495. &buf, sizeof(buf));
  496. if (r < 0)
  497. PWC_ERROR("Failed to power %s camera (%d)\n",
  498. power ? "on" : "off", r);
  499. }
  500. static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
  501. {
  502. unsigned char buf;
  503. /* useful range is 0x01..0x20 */
  504. buf = speed / 0x7f0;
  505. return send_control_msg(pdev,
  506. SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
  507. }
  508. static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
  509. {
  510. unsigned char buf;
  511. int ret;
  512. ret = recv_control_msg(pdev,
  513. GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
  514. if (ret < 0)
  515. return ret;
  516. *value = buf * 0x7f0;
  517. return 0;
  518. }
  519. static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
  520. {
  521. unsigned char buf;
  522. /* useful range is 0x01..0x3F */
  523. buf = (delay >> 10);
  524. return send_control_msg(pdev,
  525. SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
  526. }
  527. static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
  528. {
  529. unsigned char buf;
  530. int ret;
  531. ret = recv_control_msg(pdev,
  532. GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
  533. if (ret < 0)
  534. return ret;
  535. *value = buf << 10;
  536. return 0;
  537. }
  538. int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
  539. {
  540. unsigned char buf[2];
  541. int r;
  542. if (pdev->type < 730)
  543. return 0;
  544. on_value /= 100;
  545. off_value /= 100;
  546. if (on_value < 0)
  547. on_value = 0;
  548. if (on_value > 0xff)
  549. on_value = 0xff;
  550. if (off_value < 0)
  551. off_value = 0;
  552. if (off_value > 0xff)
  553. off_value = 0xff;
  554. buf[0] = on_value;
  555. buf[1] = off_value;
  556. r = send_control_msg(pdev,
  557. SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
  558. if (r < 0)
  559. PWC_ERROR("Failed to set LED on/off time (%d)\n", r);
  560. return r;
  561. }
  562. static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
  563. {
  564. unsigned char buf[2];
  565. int ret;
  566. if (pdev->type < 730) {
  567. *on_value = -1;
  568. *off_value = -1;
  569. return 0;
  570. }
  571. ret = recv_control_msg(pdev,
  572. GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
  573. if (ret < 0)
  574. return ret;
  575. *on_value = buf[0] * 100;
  576. *off_value = buf[1] * 100;
  577. return 0;
  578. }
  579. static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
  580. {
  581. unsigned char buf;
  582. buf = flags & 0x03; // only lower two bits are currently used
  583. return send_control_msg(pdev,
  584. SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf));
  585. }
  586. int pwc_mpt_reset(struct pwc_device *pdev, int flags)
  587. {
  588. int ret;
  589. ret = _pwc_mpt_reset(pdev, flags);
  590. if (ret >= 0) {
  591. pdev->pan_angle = 0;
  592. pdev->tilt_angle = 0;
  593. }
  594. return ret;
  595. }
  596. static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
  597. {
  598. unsigned char buf[4];
  599. /* set new relative angle; angles are expressed in degrees * 100,
  600. but cam as .5 degree resolution, hence divide by 200. Also
  601. the angle must be multiplied by 64 before it's send to
  602. the cam (??)
  603. */
  604. pan = 64 * pan / 100;
  605. tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */
  606. buf[0] = pan & 0xFF;
  607. buf[1] = (pan >> 8) & 0xFF;
  608. buf[2] = tilt & 0xFF;
  609. buf[3] = (tilt >> 8) & 0xFF;
  610. return send_control_msg(pdev,
  611. SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf));
  612. }
  613. int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
  614. {
  615. int ret;
  616. /* check absolute ranges */
  617. if (pan < pdev->angle_range.pan_min ||
  618. pan > pdev->angle_range.pan_max ||
  619. tilt < pdev->angle_range.tilt_min ||
  620. tilt > pdev->angle_range.tilt_max)
  621. return -ERANGE;
  622. /* go to relative range, check again */
  623. pan -= pdev->pan_angle;
  624. tilt -= pdev->tilt_angle;
  625. /* angles are specified in degrees * 100, thus the limit = 36000 */
  626. if (pan < -36000 || pan > 36000 || tilt < -36000 || tilt > 36000)
  627. return -ERANGE;
  628. ret = _pwc_mpt_set_angle(pdev, pan, tilt);
  629. if (ret >= 0) {
  630. pdev->pan_angle += pan;
  631. pdev->tilt_angle += tilt;
  632. }
  633. if (ret == -EPIPE) /* stall -> out of range */
  634. ret = -ERANGE;
  635. return ret;
  636. }
  637. static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status)
  638. {
  639. int ret;
  640. unsigned char buf[5];
  641. ret = recv_control_msg(pdev,
  642. GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf));
  643. if (ret < 0)
  644. return ret;
  645. status->status = buf[0] & 0x7; // 3 bits are used for reporting
  646. status->time_pan = (buf[1] << 8) + buf[2];
  647. status->time_tilt = (buf[3] << 8) + buf[4];
  648. return 0;
  649. }
  650. #ifdef CONFIG_USB_PWC_DEBUG
  651. int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
  652. {
  653. unsigned char buf;
  654. int ret = -1, request;
  655. if (pdev->type < 675)
  656. request = SENSOR_TYPE_FORMATTER1;
  657. else if (pdev->type < 730)
  658. return -1; /* The Vesta series doesn't have this call */
  659. else
  660. request = SENSOR_TYPE_FORMATTER2;
  661. ret = recv_control_msg(pdev,
  662. GET_STATUS_CTL, request, &buf, sizeof(buf));
  663. if (ret < 0)
  664. return ret;
  665. if (pdev->type < 675)
  666. *sensor = buf | 0x100;
  667. else
  668. *sensor = buf;
  669. return 0;
  670. }
  671. #endif
  672. /* End of Add-Ons */
  673. /* ************************************************* */
  674. /* Linux 2.5.something and 2.6 pass direct pointers to arguments of
  675. ioctl() calls. With 2.4, you have to do tedious copy_from_user()
  676. and copy_to_user() calls. With these macros we circumvent this,
  677. and let me maintain only one source file. The functionality is
  678. exactly the same otherwise.
  679. */
  680. /* define local variable for arg */
  681. #define ARG_DEF(ARG_type, ARG_name)\
  682. ARG_type *ARG_name = arg;
  683. /* copy arg to local variable */
  684. #define ARG_IN(ARG_name) /* nothing */
  685. /* argument itself (referenced) */
  686. #define ARGR(ARG_name) (*ARG_name)
  687. /* argument address */
  688. #define ARGA(ARG_name) ARG_name
  689. /* copy local variable to arg */
  690. #define ARG_OUT(ARG_name) /* nothing */
  691. /*
  692. * Our ctrls use native values, but the old custom pwc ioctl interface expects
  693. * values from 0 - 65535, define 2 helper functions to scale things. */
  694. static int pwc_ioctl_g_ctrl(struct v4l2_ctrl *ctrl)
  695. {
  696. return v4l2_ctrl_g_ctrl(ctrl) * 65535 / ctrl->maximum;
  697. }
  698. static int pwc_ioctl_s_ctrl(struct v4l2_ctrl *ctrl, int val)
  699. {
  700. return v4l2_ctrl_s_ctrl(ctrl, val * ctrl->maximum / 65535);
  701. }
  702. long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
  703. {
  704. long ret = 0;
  705. switch(cmd) {
  706. case VIDIOCPWCRUSER:
  707. ret = pwc_button_ctrl(pdev, RESTORE_USER_DEFAULTS_FORMATTER);
  708. break;
  709. case VIDIOCPWCSUSER:
  710. ret = pwc_button_ctrl(pdev, SAVE_USER_DEFAULTS_FORMATTER);
  711. break;
  712. case VIDIOCPWCFACTORY:
  713. ret = pwc_button_ctrl(pdev, RESTORE_FACTORY_DEFAULTS_FORMATTER);
  714. break;
  715. case VIDIOCPWCSCQUAL:
  716. {
  717. ARG_DEF(int, qual)
  718. if (vb2_is_streaming(&pdev->vb_queue)) {
  719. ret = -EBUSY;
  720. break;
  721. }
  722. ARG_IN(qual)
  723. if (ARGR(qual) < 0 || ARGR(qual) > 3)
  724. ret = -EINVAL;
  725. else
  726. ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
  727. break;
  728. }
  729. case VIDIOCPWCGCQUAL:
  730. {
  731. ARG_DEF(int, qual)
  732. ARGR(qual) = pdev->vcompression;
  733. ARG_OUT(qual)
  734. break;
  735. }
  736. case VIDIOCPWCPROBE:
  737. {
  738. ARG_DEF(struct pwc_probe, probe)
  739. strcpy(ARGR(probe).name, pdev->vdev.name);
  740. ARGR(probe).type = pdev->type;
  741. ARG_OUT(probe)
  742. break;
  743. }
  744. case VIDIOCPWCGSERIAL:
  745. {
  746. ARG_DEF(struct pwc_serial, serial)
  747. strcpy(ARGR(serial).serial, pdev->serial);
  748. ARG_OUT(serial)
  749. break;
  750. }
  751. case VIDIOCPWCSAGC:
  752. {
  753. ARG_DEF(int, agc)
  754. ARG_IN(agc)
  755. ret = v4l2_ctrl_s_ctrl(pdev->autogain, ARGR(agc) < 0);
  756. if (ret == 0 && ARGR(agc) >= 0)
  757. ret = pwc_ioctl_s_ctrl(pdev->gain, ARGR(agc));
  758. break;
  759. }
  760. case VIDIOCPWCGAGC:
  761. {
  762. ARG_DEF(int, agc)
  763. if (v4l2_ctrl_g_ctrl(pdev->autogain))
  764. ARGR(agc) = -1;
  765. else
  766. ARGR(agc) = pwc_ioctl_g_ctrl(pdev->gain);
  767. ARG_OUT(agc)
  768. break;
  769. }
  770. case VIDIOCPWCSSHUTTER:
  771. {
  772. ARG_DEF(int, shutter)
  773. ARG_IN(shutter)
  774. ret = v4l2_ctrl_s_ctrl(pdev->exposure_auto,
  775. /* Menu idx 0 = auto, idx 1 = manual */
  776. ARGR(shutter) >= 0);
  777. if (ret == 0 && ARGR(shutter) >= 0)
  778. ret = pwc_ioctl_s_ctrl(pdev->exposure, ARGR(shutter));
  779. break;
  780. }
  781. case VIDIOCPWCSAWB:
  782. {
  783. ARG_DEF(struct pwc_whitebalance, wb)
  784. ARG_IN(wb)
  785. ret = v4l2_ctrl_s_ctrl(pdev->auto_white_balance,
  786. ARGR(wb).mode);
  787. if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL)
  788. ret = pwc_ioctl_s_ctrl(pdev->red_balance,
  789. ARGR(wb).manual_red);
  790. if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL)
  791. ret = pwc_ioctl_s_ctrl(pdev->blue_balance,
  792. ARGR(wb).manual_blue);
  793. break;
  794. }
  795. case VIDIOCPWCGAWB:
  796. {
  797. ARG_DEF(struct pwc_whitebalance, wb)
  798. ARGR(wb).mode = v4l2_ctrl_g_ctrl(pdev->auto_white_balance);
  799. ARGR(wb).manual_red = ARGR(wb).read_red =
  800. pwc_ioctl_g_ctrl(pdev->red_balance);
  801. ARGR(wb).manual_blue = ARGR(wb).read_blue =
  802. pwc_ioctl_g_ctrl(pdev->blue_balance);
  803. ARG_OUT(wb)
  804. break;
  805. }
  806. case VIDIOCPWCSAWBSPEED:
  807. {
  808. ARG_DEF(struct pwc_wb_speed, wbs)
  809. if (ARGR(wbs).control_speed > 0) {
  810. ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
  811. }
  812. if (ARGR(wbs).control_delay > 0) {
  813. ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
  814. }
  815. break;
  816. }
  817. case VIDIOCPWCGAWBSPEED:
  818. {
  819. ARG_DEF(struct pwc_wb_speed, wbs)
  820. ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
  821. if (ret < 0)
  822. break;
  823. ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
  824. if (ret < 0)
  825. break;
  826. ARG_OUT(wbs)
  827. break;
  828. }
  829. case VIDIOCPWCSLED:
  830. {
  831. ARG_DEF(struct pwc_leds, leds)
  832. ARG_IN(leds)
  833. ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
  834. break;
  835. }
  836. case VIDIOCPWCGLED:
  837. {
  838. ARG_DEF(struct pwc_leds, leds)
  839. ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
  840. ARG_OUT(leds)
  841. break;
  842. }
  843. case VIDIOCPWCSCONTOUR:
  844. {
  845. ARG_DEF(int, contour)
  846. ARG_IN(contour)
  847. ret = v4l2_ctrl_s_ctrl(pdev->autocontour, ARGR(contour) < 0);
  848. if (ret == 0 && ARGR(contour) >= 0)
  849. ret = pwc_ioctl_s_ctrl(pdev->contour, ARGR(contour));
  850. break;
  851. }
  852. case VIDIOCPWCGCONTOUR:
  853. {
  854. ARG_DEF(int, contour)
  855. if (v4l2_ctrl_g_ctrl(pdev->autocontour))
  856. ARGR(contour) = -1;
  857. else
  858. ARGR(contour) = pwc_ioctl_g_ctrl(pdev->contour);
  859. ARG_OUT(contour)
  860. break;
  861. }
  862. case VIDIOCPWCSBACKLIGHT:
  863. {
  864. ARG_DEF(int, backlight)
  865. ARG_IN(backlight)
  866. ret = v4l2_ctrl_s_ctrl(pdev->backlight, ARGR(backlight));
  867. break;
  868. }
  869. case VIDIOCPWCGBACKLIGHT:
  870. {
  871. ARG_DEF(int, backlight)
  872. ARGR(backlight) = v4l2_ctrl_g_ctrl(pdev->backlight);
  873. ARG_OUT(backlight)
  874. break;
  875. }
  876. case VIDIOCPWCSFLICKER:
  877. {
  878. ARG_DEF(int, flicker)
  879. ARG_IN(flicker)
  880. ret = v4l2_ctrl_s_ctrl(pdev->flicker, ARGR(flicker));
  881. break;
  882. }
  883. case VIDIOCPWCGFLICKER:
  884. {
  885. ARG_DEF(int, flicker)
  886. ARGR(flicker) = v4l2_ctrl_g_ctrl(pdev->flicker);
  887. ARG_OUT(flicker)
  888. break;
  889. }
  890. case VIDIOCPWCSDYNNOISE:
  891. {
  892. ARG_DEF(int, dynnoise)
  893. ARG_IN(dynnoise)
  894. ret = v4l2_ctrl_s_ctrl(pdev->noise_reduction, ARGR(dynnoise));
  895. break;
  896. }
  897. case VIDIOCPWCGDYNNOISE:
  898. {
  899. ARG_DEF(int, dynnoise)
  900. ARGR(dynnoise) = v4l2_ctrl_g_ctrl(pdev->noise_reduction);
  901. ARG_OUT(dynnoise);
  902. break;
  903. }
  904. case VIDIOCPWCGREALSIZE:
  905. {
  906. ARG_DEF(struct pwc_imagesize, size)
  907. ARGR(size).width = pdev->image.x;
  908. ARGR(size).height = pdev->image.y;
  909. ARG_OUT(size)
  910. break;
  911. }
  912. case VIDIOCPWCMPTRESET:
  913. {
  914. if (pdev->features & FEATURE_MOTOR_PANTILT)
  915. {
  916. ARG_DEF(int, flags)
  917. ARG_IN(flags)
  918. ret = pwc_mpt_reset(pdev, ARGR(flags));
  919. }
  920. else
  921. {
  922. ret = -ENXIO;
  923. }
  924. break;
  925. }
  926. case VIDIOCPWCMPTGRANGE:
  927. {
  928. if (pdev->features & FEATURE_MOTOR_PANTILT)
  929. {
  930. ARG_DEF(struct pwc_mpt_range, range)
  931. ARGR(range) = pdev->angle_range;
  932. ARG_OUT(range)
  933. }
  934. else
  935. {
  936. ret = -ENXIO;
  937. }
  938. break;
  939. }
  940. case VIDIOCPWCMPTSANGLE:
  941. {
  942. int new_pan, new_tilt;
  943. if (pdev->features & FEATURE_MOTOR_PANTILT)
  944. {
  945. ARG_DEF(struct pwc_mpt_angles, angles)
  946. ARG_IN(angles)
  947. /* The camera can only set relative angles, so
  948. do some calculations when getting an absolute angle .
  949. */
  950. if (ARGR(angles).absolute)
  951. {
  952. new_pan = ARGR(angles).pan;
  953. new_tilt = ARGR(angles).tilt;
  954. }
  955. else
  956. {
  957. new_pan = pdev->pan_angle + ARGR(angles).pan;
  958. new_tilt = pdev->tilt_angle + ARGR(angles).tilt;
  959. }
  960. ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
  961. }
  962. else
  963. {
  964. ret = -ENXIO;
  965. }
  966. break;
  967. }
  968. case VIDIOCPWCMPTGANGLE:
  969. {
  970. if (pdev->features & FEATURE_MOTOR_PANTILT)
  971. {
  972. ARG_DEF(struct pwc_mpt_angles, angles)
  973. ARGR(angles).absolute = 1;
  974. ARGR(angles).pan = pdev->pan_angle;
  975. ARGR(angles).tilt = pdev->tilt_angle;
  976. ARG_OUT(angles)
  977. }
  978. else
  979. {
  980. ret = -ENXIO;
  981. }
  982. break;
  983. }
  984. case VIDIOCPWCMPTSTATUS:
  985. {
  986. if (pdev->features & FEATURE_MOTOR_PANTILT)
  987. {
  988. ARG_DEF(struct pwc_mpt_status, status)
  989. ret = pwc_mpt_get_status(pdev, ARGA(status));
  990. ARG_OUT(status)
  991. }
  992. else
  993. {
  994. ret = -ENXIO;
  995. }
  996. break;
  997. }
  998. case VIDIOCPWCGVIDCMD:
  999. {
  1000. ARG_DEF(struct pwc_video_command, vcmd);
  1001. ARGR(vcmd).type = pdev->type;
  1002. ARGR(vcmd).release = pdev->release;
  1003. ARGR(vcmd).command_len = pdev->cmd_len;
  1004. memcpy(&ARGR(vcmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
  1005. ARGR(vcmd).bandlength = pdev->vbandlength;
  1006. ARGR(vcmd).frame_size = pdev->frame_size;
  1007. ARG_OUT(vcmd)
  1008. break;
  1009. }
  1010. /*
  1011. case VIDIOCPWCGVIDTABLE:
  1012. {
  1013. ARG_DEF(struct pwc_table_init_buffer, table);
  1014. ARGR(table).len = pdev->cmd_len;
  1015. memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size);
  1016. ARG_OUT(table)
  1017. break;
  1018. }
  1019. */
  1020. default:
  1021. ret = -ENOIOCTLCMD;
  1022. break;
  1023. }
  1024. if (ret > 0)
  1025. return 0;
  1026. return ret;
  1027. }
  1028. /* vim: set cinoptions= formatoptions=croql cindent shiftwidth=8 tabstop=8: */