ultracam.c 21 KB

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