ultracam.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:22k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * USB NB Camera driver
  3.  */
  4. #include <linux/kernel.h>
  5. #include <linux/sched.h>
  6. #include <linux/wrapper.h>
  7. #include <linux/module.h>
  8. #include <linux/init.h>
  9. #include "usbvideo.h"
  10. #define ULTRACAM_VENDOR_ID 0x0461
  11. #define ULTRACAM_PRODUCT_ID 0x0813
  12. #define MAX_CAMERAS 4 /* How many devices we allow to connect */
  13. /*
  14.  * This structure lives in uvd_t->user field.
  15.  */
  16. typedef struct {
  17. int initialized; /* Had we already sent init sequence? */
  18. int camera_model; /* What type of IBM camera we got? */
  19.         int has_hdr;
  20. } ultracam_t;
  21. #define ULTRACAM_T(uvd) ((ultracam_t *)((uvd)->user_data))
  22. static usbvideo_t *cams = NULL;
  23. static int debug = 0;
  24. static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
  25. static const int min_canvasWidth  = 8;
  26. static const int min_canvasHeight = 4;
  27. //static int lighting = 1; /* Medium */
  28. #define SHARPNESS_MIN 0
  29. #define SHARPNESS_MAX 6
  30. //static int sharpness = 4; /* Low noise, good details */
  31. #define FRAMERATE_MIN 0
  32. #define FRAMERATE_MAX 6
  33. static int framerate = -1;
  34. /*
  35.  * Here we define several initialization variables. They may
  36.  * be used to automatically set color, hue, brightness and
  37.  * contrast to desired values. This is particularly useful in
  38.  * case of webcams (which have no controls and no on-screen
  39.  * output) and also when a client V4L software is used that
  40.  * does not have some of those controls. In any case it's
  41.  * good to have startup values as options.
  42.  *
  43.  * These values are all in [0..255] range. This simplifies
  44.  * operation. Note that actual values of V4L variables may
  45.  * be scaled up (as much as << 8). User can see that only
  46.  * on overlay output, however, or through a V4L client.
  47.  */
  48. static int init_brightness = 128;
  49. static int init_contrast = 192;
  50. static int init_color = 128;
  51. static int init_hue = 128;
  52. static int hue_correction = 128;
  53. MODULE_PARM(debug, "i");
  54. MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
  55. MODULE_PARM(flags, "i");
  56. MODULE_PARM_DESC(flags,
  57. "Bitfield: 0=VIDIOCSYNC, "
  58. "1=B/W, "
  59. "2=show hints, "
  60. "3=show stats, "
  61. "4=test pattern, "
  62. "5=separate frames, "
  63. "6=clean frames");
  64. MODULE_PARM(framerate, "i");
  65. MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
  66. MODULE_PARM(lighting, "i");
  67. MODULE_PARM_DESC(lighting, "Photosensitivity: 0=bright, 1=medium (default), 2=low light");
  68. MODULE_PARM(sharpness, "i");
  69. MODULE_PARM_DESC(sharpness, "Model1 noise reduction: 0=smooth, 6=sharp (default=4)");
  70. MODULE_PARM(init_brightness, "i");
  71. MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
  72. MODULE_PARM(init_contrast, "i");
  73. MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
  74. MODULE_PARM(init_color, "i");
  75. MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
  76. MODULE_PARM(init_hue, "i");
  77. MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
  78. MODULE_PARM(hue_correction, "i");
  79. MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
  80. /*
  81.  * ultracam_ProcessIsocData()
  82.  *
  83.  * Generic routine to parse the ring queue data. It employs either
  84.  * ultracam_find_header() or ultracam_parse_lines() to do most
  85.  * of work.
  86.  *
  87.  * 02-Nov-2000 First (mostly dummy) version.
  88.  * 06-Nov-2000 Rewrote to dump all data into frame.
  89.  */
  90. void ultracam_ProcessIsocData(uvd_t *uvd, usbvideo_frame_t *frame)
  91. {
  92. int n;
  93. assert(uvd != NULL);
  94. assert(frame != NULL);
  95. /* Try to move data from queue into frame buffer */
  96. n = RingQueue_GetLength(&uvd->dp);
  97. if (n > 0) {
  98. int m;
  99. /* See how much spare we have left */
  100. m = uvd->max_frame_size - frame->seqRead_Length;
  101. if (n > m)
  102. n = m;
  103. /* Now move that much data into frame buffer */
  104. RingQueue_Dequeue(
  105. &uvd->dp,
  106. frame->data + frame->seqRead_Length,
  107. m);
  108. frame->seqRead_Length += m;
  109. }
  110. /* See if we filled the frame */
  111. if (frame->seqRead_Length >= uvd->max_frame_size) {
  112. frame->frameState = FrameState_Done;
  113. uvd->curframe = -1;
  114. uvd->stats.frame_num++;
  115. }
  116. }
  117. /*
  118.  * ultracam_veio()
  119.  *
  120.  * History:
  121.  * 1/27/00  Added check for dev == NULL; this happens if camera is unplugged.
  122.  */
  123. static int ultracam_veio(
  124. uvd_t *uvd,
  125. unsigned char req,
  126. unsigned short value,
  127. unsigned short index,
  128. int is_out)
  129. {
  130. static const char proc[] = "ultracam_veio";
  131. unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
  132. int i;
  133. if (!CAMERA_IS_OPERATIONAL(uvd))
  134. return 0;
  135. if (!is_out) {
  136. i = usb_control_msg(
  137. uvd->dev,
  138. usb_rcvctrlpipe(uvd->dev, 0),
  139. req,
  140. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  141. value,
  142. index,
  143. cp,
  144. sizeof(cp),
  145. HZ);
  146. #if 1
  147. info("USB => %02x%02x%02x%02x%02x%02x%02x%02x "
  148.        "(req=$%02x val=$%04x ind=$%04x)",
  149.        cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
  150.        req, value, index);
  151. #endif
  152. } else {
  153. i = usb_control_msg(
  154. uvd->dev,
  155. usb_sndctrlpipe(uvd->dev, 0),
  156. req,
  157. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  158. value,
  159. index,
  160. NULL,
  161. 0,
  162. HZ);
  163. }
  164. if (i < 0) {
  165. err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",
  166.     proc, i);
  167. uvd->last_error = i;
  168. }
  169. return i;
  170. }
  171. /*
  172.  * ultracam_calculate_fps()
  173.  */
  174. static int ultracam_calculate_fps(uvd_t *uvd)
  175. {
  176. return 3 + framerate*4 + framerate/2;
  177. }
  178. /*
  179.  * ultracam_adjust_contrast()
  180.  */
  181. static void ultracam_adjust_contrast(uvd_t *uvd)
  182. {
  183. }
  184. /*
  185.  * ultracam_change_lighting_conditions()
  186.  */
  187. static void ultracam_change_lighting_conditions(uvd_t *uvd)
  188. {
  189. }
  190. /*
  191.  * ultracam_set_sharpness()
  192.  *
  193.  * Cameras model 1 have internal smoothing feature. It is controlled by value in
  194.  * range [0..6], where 0 is most smooth and 6 is most sharp (raw image, I guess).
  195.  * Recommended value is 4. Cameras model 2 do not have this feature at all.
  196.  */
  197. static void ultracam_set_sharpness(uvd_t *uvd)
  198. {
  199. }
  200. /*
  201.  * ultracam_set_brightness()
  202.  *
  203.  * This procedure changes brightness of the picture.
  204.  */
  205. static void ultracam_set_brightness(uvd_t *uvd)
  206. {
  207. }
  208. static void ultracam_set_hue(uvd_t *uvd)
  209. {
  210. }
  211. /*
  212.  * ultracam_adjust_picture()
  213.  *
  214.  * This procedure gets called from V4L interface to update picture settings.
  215.  * Here we change brightness and contrast.
  216.  */
  217. static void ultracam_adjust_picture(uvd_t *uvd)
  218. {
  219. ultracam_adjust_contrast(uvd);
  220. ultracam_set_brightness(uvd);
  221. ultracam_set_hue(uvd);
  222. }
  223. /*
  224.  * ultracam_video_stop()
  225.  *
  226.  * This code tells camera to stop streaming. The interface remains
  227.  * configured and bandwidth - claimed.
  228.  */
  229. static void ultracam_video_stop(uvd_t *uvd)
  230. {
  231. }
  232. /*
  233.  * ultracam_reinit_iso()
  234.  *
  235.  * This procedure sends couple of commands to the camera and then
  236.  * resets the video pipe. This sequence was observed to reinit the
  237.  * camera or, at least, to initiate ISO data stream.
  238.  */
  239. static void ultracam_reinit_iso(uvd_t *uvd, int do_stop)
  240. {
  241. }
  242. static void ultracam_video_start(uvd_t *uvd)
  243. {
  244. ultracam_change_lighting_conditions(uvd);
  245. ultracam_set_sharpness(uvd);
  246. ultracam_reinit_iso(uvd, 0);
  247. }
  248. static int ultracam_resetPipe(uvd_t *uvd)
  249. {
  250. usb_clear_halt(uvd->dev, uvd->video_endp);
  251. return 0;
  252. }
  253. static int ultracam_alternateSetting(uvd_t *uvd, int setting)
  254. {
  255. static const char proc[] = "ultracam_alternateSetting";
  256. int i;
  257. i = usb_set_interface(uvd->dev, uvd->iface, setting);
  258. if (i < 0) {
  259. err("%s: usb_set_interface error", proc);
  260. uvd->last_error = i;
  261. return -EBUSY;
  262. }
  263. return 0;
  264. }
  265. /*
  266.  * Return negative code on failure, 0 on success.
  267.  */
  268. static int ultracam_setup_on_open(uvd_t *uvd)
  269. {
  270. int setup_ok = 0; /* Success by default */
  271. /* Send init sequence only once, it's large! */
  272. if (!ULTRACAM_T(uvd)->initialized) {
  273. ultracam_alternateSetting(uvd, 0x04);
  274. ultracam_alternateSetting(uvd, 0x00);
  275. ultracam_veio(uvd, 0x02, 0x0004, 0x000b, 1);
  276. ultracam_veio(uvd, 0x02, 0x0001, 0x0005, 1);
  277. ultracam_veio(uvd, 0x02, 0x8000, 0x0000, 1);
  278. ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1);
  279. ultracam_veio(uvd, 0x00, 0x00b0, 0x0001, 1);
  280. ultracam_veio(uvd, 0x00, 0x0000, 0x0002, 1);
  281. ultracam_veio(uvd, 0x00, 0x000c, 0x0003, 1);
  282. ultracam_veio(uvd, 0x00, 0x000b, 0x0004, 1);
  283. ultracam_veio(uvd, 0x00, 0x0000, 0x0005, 1);
  284. ultracam_veio(uvd, 0x00, 0x0000, 0x0006, 1);
  285. ultracam_veio(uvd, 0x00, 0x0079, 0x0007, 1);
  286. ultracam_veio(uvd, 0x00, 0x003b, 0x0008, 1);
  287. ultracam_veio(uvd, 0x00, 0x0002, 0x000f, 1);
  288. ultracam_veio(uvd, 0x00, 0x0001, 0x0010, 1);
  289. ultracam_veio(uvd, 0x00, 0x0000, 0x0011, 1);
  290. ultracam_veio(uvd, 0x00, 0x0000, 0x00bf, 1);
  291. ultracam_veio(uvd, 0x00, 0x0001, 0x00c0, 1);
  292. ultracam_veio(uvd, 0x00, 0x0010, 0x00cb, 1);
  293. ultracam_veio(uvd, 0x01, 0x00a4, 0x0001, 1);
  294. ultracam_veio(uvd, 0x01, 0x0010, 0x0002, 1);
  295. ultracam_veio(uvd, 0x01, 0x0066, 0x0007, 1);
  296. ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1);
  297. ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1);
  298. ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1);
  299. ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1);
  300. ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1);
  301. ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1);
  302. ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1);
  303. ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1);
  304. ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1);
  305. ultracam_veio(uvd, 0x01, 0x000b, 0x0011, 1);
  306. ultracam_veio(uvd, 0x01, 0x0001, 0x0012, 1);
  307. ultracam_veio(uvd, 0x01, 0x0000, 0x0013, 1);
  308. ultracam_veio(uvd, 0x01, 0x0000, 0x0014, 1);
  309. ultracam_veio(uvd, 0x01, 0x0087, 0x0051, 1);
  310. ultracam_veio(uvd, 0x01, 0x0040, 0x0052, 1);
  311. ultracam_veio(uvd, 0x01, 0x0058, 0x0053, 1);
  312. ultracam_veio(uvd, 0x01, 0x0040, 0x0054, 1);
  313. ultracam_veio(uvd, 0x01, 0x0000, 0x0040, 1);
  314. ultracam_veio(uvd, 0x01, 0x0010, 0x0041, 1);
  315. ultracam_veio(uvd, 0x01, 0x0020, 0x0042, 1);
  316. ultracam_veio(uvd, 0x01, 0x0030, 0x0043, 1);
  317. ultracam_veio(uvd, 0x01, 0x0040, 0x0044, 1);
  318. ultracam_veio(uvd, 0x01, 0x0050, 0x0045, 1);
  319. ultracam_veio(uvd, 0x01, 0x0060, 0x0046, 1);
  320. ultracam_veio(uvd, 0x01, 0x0070, 0x0047, 1);
  321. ultracam_veio(uvd, 0x01, 0x0080, 0x0048, 1);
  322. ultracam_veio(uvd, 0x01, 0x0090, 0x0049, 1);
  323. ultracam_veio(uvd, 0x01, 0x00a0, 0x004a, 1);
  324. ultracam_veio(uvd, 0x01, 0x00b0, 0x004b, 1);
  325. ultracam_veio(uvd, 0x01, 0x00c0, 0x004c, 1);
  326. ultracam_veio(uvd, 0x01, 0x00d0, 0x004d, 1);
  327. ultracam_veio(uvd, 0x01, 0x00e0, 0x004e, 1);
  328. ultracam_veio(uvd, 0x01, 0x00f0, 0x004f, 1);
  329. ultracam_veio(uvd, 0x01, 0x00ff, 0x0050, 1);
  330. ultracam_veio(uvd, 0x01, 0x0000, 0x0056, 1);
  331. ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1);
  332. ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1);
  333. ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
  334. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  335. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  336. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  337. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  338. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  339. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  340. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  341. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  342. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  343. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  344. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  345. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  346. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  347. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  348. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  349. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  350. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  351. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  352. ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1);
  353. ultracam_veio(uvd, 0x00, 0x0004, 0x00c2, 1);
  354. ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
  355. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  356. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  357. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  358. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  359. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  360. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  361. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  362. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  363. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  364. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  365. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  366. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  367. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  368. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  369. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  370. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  371. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  372. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  373. ultracam_veio(uvd, 0x00, 0x0002, 0x00c1, 1);
  374. ultracam_veio(uvd, 0x00, 0x0020, 0x00c2, 1);
  375. ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
  376. ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
  377. ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
  378. ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
  379. ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
  380. ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
  381. ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
  382. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  383. ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
  384. ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
  385. ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
  386. ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
  387. ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
  388. ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
  389. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  390. ultracam_veio(uvd, 0x00, 0x0040, 0x00c1, 1);
  391. ultracam_veio(uvd, 0x00, 0x0017, 0x00c2, 1);
  392. ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
  393. ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
  394. ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
  395. ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
  396. ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
  397. ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
  398. ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
  399. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  400. ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
  401. ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
  402. ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
  403. ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
  404. ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
  405. ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
  406. ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
  407. ultracam_veio(uvd, 0x00, 0x00c0, 0x00c1, 1);
  408. ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1);
  409. ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
  410. ultracam_veio(uvd, 0x02, 0xc040, 0x0001, 1);
  411. ultracam_veio(uvd, 0x01, 0x0000, 0x0008, 0);
  412. ultracam_veio(uvd, 0x01, 0x0000, 0x0009, 0);
  413. ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 0);
  414. ultracam_veio(uvd, 0x01, 0x0000, 0x000b, 0);
  415. ultracam_veio(uvd, 0x01, 0x0000, 0x000c, 0);
  416. ultracam_veio(uvd, 0x01, 0x0000, 0x000d, 0);
  417. ultracam_veio(uvd, 0x01, 0x0000, 0x000e, 0);
  418. ultracam_veio(uvd, 0x01, 0x0000, 0x000f, 0);
  419. ultracam_veio(uvd, 0x01, 0x0000, 0x0010, 0);
  420. ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1);
  421. ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1);
  422. ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1);
  423. ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1);
  424. ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1);
  425. ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1);
  426. ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1);
  427. ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1);
  428. ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1);
  429. ultracam_veio(uvd, 0x01, 0x0000, 0x0001, 0);
  430. ultracam_veio(uvd, 0x01, 0x0064, 0x0001, 1);
  431. ultracam_veio(uvd, 0x01, 0x0059, 0x0051, 1);
  432. ultracam_veio(uvd, 0x01, 0x003f, 0x0052, 1);
  433. ultracam_veio(uvd, 0x01, 0x0094, 0x0053, 1);
  434. ultracam_veio(uvd, 0x01, 0x00ff, 0x0011, 1);
  435. ultracam_veio(uvd, 0x01, 0x0003, 0x0012, 1);
  436. ultracam_veio(uvd, 0x01, 0x00f7, 0x0013, 1);
  437. ultracam_veio(uvd, 0x00, 0x0009, 0x0011, 1);
  438. ultracam_veio(uvd, 0x00, 0x0000, 0x0001, 1);
  439. ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1);
  440. ultracam_veio(uvd, 0x00, 0x0020, 0x00c1, 1);
  441. ultracam_veio(uvd, 0x00, 0x0010, 0x00c2, 1);
  442. ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
  443. ultracam_alternateSetting(uvd, 0x04);
  444. ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1);
  445. ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1);
  446. ultracam_veio(uvd, 0x02, 0x0000, 0x0006, 1);
  447. ultracam_veio(uvd, 0x02, 0x9000, 0x0007, 1);
  448. ultracam_veio(uvd, 0x02, 0x0042, 0x0001, 1);
  449. ultracam_veio(uvd, 0x02, 0x0000, 0x000b, 0);
  450. ultracam_resetPipe(uvd);
  451. ULTRACAM_T(uvd)->initialized = (setup_ok != 0);
  452. }
  453. return setup_ok;
  454. }
  455. static void ultracam_configure_video(uvd_t *uvd)
  456. {
  457. if (uvd == NULL)
  458. return;
  459. RESTRICT_TO_RANGE(init_brightness, 0, 255);
  460. RESTRICT_TO_RANGE(init_contrast, 0, 255);
  461. RESTRICT_TO_RANGE(init_color, 0, 255);
  462. RESTRICT_TO_RANGE(init_hue, 0, 255);
  463. RESTRICT_TO_RANGE(hue_correction, 0, 255);
  464. memset(&uvd->vpic, 0, sizeof(uvd->vpic));
  465. memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
  466. uvd->vpic.colour = init_color << 8;
  467. uvd->vpic.hue = init_hue << 8;
  468. uvd->vpic.brightness = init_brightness << 8;
  469. uvd->vpic.contrast = init_contrast << 8;
  470. uvd->vpic.whiteness = 105 << 8; /* This one isn't used */
  471. uvd->vpic.depth = 24;
  472. uvd->vpic.palette = VIDEO_PALETTE_RGB24;
  473. memset(&uvd->vcap, 0, sizeof(uvd->vcap));
  474. strcpy(uvd->vcap.name, "IBM Ultra Camera");
  475. uvd->vcap.type = VID_TYPE_CAPTURE;
  476. uvd->vcap.channels = 1;
  477. uvd->vcap.audios = 0;
  478. uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas);
  479. uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas);
  480. uvd->vcap.minwidth = min_canvasWidth;
  481. uvd->vcap.minheight = min_canvasHeight;
  482. memset(&uvd->vchan, 0, sizeof(uvd->vchan));
  483. uvd->vchan.flags = 0;
  484. uvd->vchan.tuners = 0;
  485. uvd->vchan.channel = 0;
  486. uvd->vchan.type = VIDEO_TYPE_CAMERA;
  487. strcpy(uvd->vchan.name, "Camera");
  488. }
  489. /*
  490.  * ultracam_probe()
  491.  *
  492.  * This procedure queries device descriptor and accepts the interface
  493.  * if it looks like our camera.
  494.  *
  495.  * History:
  496.  * 12-Nov-2000 Reworked to comply with new probe() signature.
  497.  * 23-Jan-2001 Added compatibility with 2.2.x kernels.
  498.  */
  499. static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const struct usb_device_id *devid)
  500. {
  501. uvd_t *uvd = NULL;
  502. int i, nas;
  503. int actInterface=-1, inactInterface=-1, maxPS=0;
  504. unsigned char video_ep = 0;
  505. if (debug >= 1)
  506. info("ultracam_probe(%p,%u.)", dev, ifnum);
  507. /* We don't handle multi-config cameras */
  508. if (dev->descriptor.bNumConfigurations != 1)
  509. return NULL;
  510. /* Is it an IBM camera? */
  511. if ((dev->descriptor.idVendor != ULTRACAM_VENDOR_ID) ||
  512.     (dev->descriptor.idProduct != ULTRACAM_PRODUCT_ID))
  513. return NULL;
  514. info("IBM Ultra camera found (rev. 0x%04x)", dev->descriptor.bcdDevice);
  515. /* Validate found interface: must have one ISO endpoint */
  516. nas = dev->actconfig->interface[ifnum].num_altsetting;
  517. if (debug > 0)
  518. info("Number of alternate settings=%d.", nas);
  519. if (nas < 8) {
  520. err("Too few alternate settings for this camera!");
  521. return NULL;
  522. }
  523. /* Validate all alternate settings */
  524. for (i=0; i < nas; i++) {
  525. const struct usb_interface_descriptor *interface;
  526. const struct usb_endpoint_descriptor *endpoint;
  527. interface = &dev->actconfig->interface[ifnum].altsetting[i];
  528. if (interface->bNumEndpoints != 1) {
  529. err("Interface %d. has %u. endpoints!",
  530.     ifnum, (unsigned)(interface->bNumEndpoints));
  531. return NULL;
  532. }
  533. endpoint = &interface->endpoint[0];
  534. if (video_ep == 0)
  535. video_ep = endpoint->bEndpointAddress;
  536. else if (video_ep != endpoint->bEndpointAddress) {
  537. err("Alternate settings have different endpoint addresses!");
  538. return NULL;
  539. }
  540. if ((endpoint->bmAttributes & 0x03) != 0x01) {
  541. err("Interface %d. has non-ISO endpoint!", ifnum);
  542. return NULL;
  543. }
  544. if ((endpoint->bEndpointAddress & 0x80) == 0) {
  545. err("Interface %d. has ISO OUT endpoint!", ifnum);
  546. return NULL;
  547. }
  548. if (endpoint->wMaxPacketSize == 0) {
  549. if (inactInterface < 0)
  550. inactInterface = i;
  551. else {
  552. err("More than one inactive alt. setting!");
  553. return NULL;
  554. }
  555. } else {
  556. if (actInterface < 0) {
  557. actInterface = i;
  558. maxPS = endpoint->wMaxPacketSize;
  559. if (debug > 0)
  560. info("Active setting=%d. maxPS=%d.", i, maxPS);
  561. } else {
  562. /* Got another active alt. setting */
  563. if (maxPS < endpoint->wMaxPacketSize) {
  564. /* This one is better! */
  565. actInterface = i;
  566. maxPS = endpoint->wMaxPacketSize;
  567. if (debug > 0) {
  568. info("Even better ctive setting=%d. maxPS=%d.",
  569.      i, maxPS);
  570. }
  571. }
  572. }
  573. }
  574. }
  575. if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
  576. err("Failed to recognize the camera!");
  577. return NULL;
  578. }
  579. /* Code below may sleep, need to lock module while we are here */
  580. MOD_INC_USE_COUNT;
  581. uvd = usbvideo_AllocateDevice(cams);
  582. if (uvd != NULL) {
  583. /* Here uvd is a fully allocated uvd_t object */
  584. uvd->flags = flags;
  585. uvd->debug = debug;
  586. uvd->dev = dev;
  587. uvd->iface = ifnum;
  588. uvd->ifaceAltInactive = inactInterface;
  589. uvd->ifaceAltActive = actInterface;
  590. uvd->video_endp = video_ep;
  591. uvd->iso_packet_len = maxPS;
  592. uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
  593. uvd->defaultPalette = VIDEO_PALETTE_RGB24;
  594. uvd->canvas = VIDEOSIZE(640, 480); /* FIXME */
  595. uvd->videosize = uvd->canvas; /* ultracam_size_to_videosize(size);*/
  596. /* Initialize ibmcam-specific data */
  597. assert(ULTRACAM_T(uvd) != NULL);
  598. ULTRACAM_T(uvd)->camera_model = 0; /* Not used yet */
  599. ULTRACAM_T(uvd)->initialized = 0;
  600. ultracam_configure_video(uvd);
  601. i = usbvideo_RegisterVideoDevice(uvd);
  602. if (i != 0) {
  603. err("usbvideo_RegisterVideoDevice() failed.");
  604. uvd = NULL;
  605. }
  606. }
  607. MOD_DEC_USE_COUNT;
  608. return uvd;
  609. }
  610. /*
  611.  * ultracam_init()
  612.  *
  613.  * This code is run to initialize the driver.
  614.  */
  615. static int __init ultracam_init(void)
  616. {
  617. usbvideo_cb_t cbTbl;
  618. memset(&cbTbl, 0, sizeof(cbTbl));
  619. cbTbl.probe = ultracam_probe;
  620. cbTbl.setupOnOpen = ultracam_setup_on_open;
  621. cbTbl.videoStart = ultracam_video_start;
  622. cbTbl.videoStop = ultracam_video_stop;
  623. cbTbl.processData = ultracam_ProcessIsocData;
  624. cbTbl.postProcess = usbvideo_DeinterlaceFrame;
  625. cbTbl.adjustPicture = ultracam_adjust_picture;
  626. cbTbl.getFPS = ultracam_calculate_fps;
  627. return usbvideo_register(
  628. &cams,
  629. MAX_CAMERAS,
  630. sizeof(ultracam_t),
  631. "ultracam",
  632. &cbTbl,
  633. THIS_MODULE);
  634. }
  635. static void __exit ultracam_cleanup(void)
  636. {
  637. usbvideo_Deregister(&cams);
  638. }
  639. #if defined(usb_device_id_ver)
  640. static __devinitdata struct usb_device_id id_table[] = {
  641. { USB_DEVICE(ULTRACAM_VENDOR_ID, ULTRACAM_PRODUCT_ID) },
  642. { }  /* Terminating entry */
  643. };
  644. MODULE_DEVICE_TABLE(usb, id_table);
  645. #endif /* defined(usb_device_id_ver) */
  646. MODULE_LICENSE("GPL");
  647. module_init(ultracam_init);
  648. module_exit(ultracam_cleanup);